So I am new to ReacJS and JavaScript and I am stuck on an issue. I have an application, built of functional components, and what I'm trying to do is query a DB (where the schema is 2 columns, id, and content) from one component, then pass the result of that query (which happens onClick
, see below) to another sibling component. What I have so far is this:
App.js:
const App = () => {
// *Other functions and states here*
const [content, setContent] = useState('');
const getBookContent = useCallback(async () => {
await fetch('/get_books/${id}')
.then(response =>
response.json()
.then(data => {
setContent(data.content)
})
);
}, [setContent])
return (
<React.Fragment>
<NavBar />
<div>
<BooksList books={books} getBooksList={getBooksList} getBookContent={getBookContent} />
<TextEditor getBooksList={getBooksList} getBookContent={content} />
</div>
</React.Fragment>
)
}
Booklist
is the list of buttons.
const BooksList = ({books, getBooksList, getBookContent}) => {
// *Other funcs*
return (
<React.Fragment>
<div>{books.map(book => {
return (
<div key={book.content}>
<button onClick={() => getBookContent()}>{book.content}</button>
</div>
)
})}</div>
</React.Fragment>
)
I think I am on the right sort of lines. However, I think my issue is in the parent element and getting the id for await fetch('/get_books/${id}')
. I'm not sure how I should set this, or if this is even the correct thing to do.
You have to use Template literals
instead of single quotes . and you have to provide the id through the function parameters. try this:
const getBookContent = useCallback(async (id) => {
await fetch(`/get_books/${id}`)
.then(response =>
response.json()
.then(data => {
setContent(data.content)
})
);
}, [setContent])
And then call it in your component like this:
this.props.getBookContent(ID)
You need to use backticks:
fetch(`/get_books/${id}`)
For the id, you could do it that way:
<div key={book.id}>
<button onClick={() => getBookContent(book.id)}>{book.content}</button>
</div>
Actually, you should use JavaScript currying
and you need to read about template string
. let's first fix your getBookContent
function:
const getBookContent = useCallback(id => async () => {
await fetch(`/get_books/${id}`)
.then(response =>
response.json()
)
.then(data =>
setContent(data.content)
)
}, [setContent]);
The above getBookContent
function is a currying
function that it means after passing the id
you can have a new function with the new id, the function pass another function. now pass it to the component:
~~~
<BooksList
books={books}
getBooksList={getBooksList}
getBookContent={getBookContent}
/>
~~~
And inside the BookList
component:
<>
<div>
{books.map(({ content, id }) => (
<div key={content}>
<button
onClick={getBookContent(id)}
>
{content}
</button>
</div>
)
)}
</div>
</>
Excuse me for changing your code style, I just make it easier to read based on Airbnb ESLint standards.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.