Reputation: 3029
Trying out react hooks on a simple search component. The idea is simple: user types symbols, every typed symbol initiates api query.
To achieve that I have useState
and useCallback
hooks like in the code below:
const Search = () => {
const [query, setQuery] = useState("");
const sendRequest = useCallback(() => {
console.log('sendRequest ', query);
}, [query]);
return (
<div>
<input
type="text"
value={query}
placeholder="Search"
onChange={e => {
console.log('onChange ', e.target.value);
setQuery(e.target.value);
sendRequest();
}}
/>
</div>
}
The result is that sendRequest
method always gets a previous version of query
.
onChange q
sendRequest
onChange qu
sendRequest q
onChange que
sendRequest qu
Why is that? I assume that this is not how the hooks are supposed to be used, but I can't figure that out from the documentation.
Upvotes: 0
Views: 356
Reputation: 8774
setState is asynchronous! At the time you send sendRequest, the local state is not updated, because it is asynchronous and it needs some time to get set.
You should either give the string as a parameter into the function or useEffect and listen to changes of query.
Exchanging useCallback with useEffect and removing the call in onChange should work.
const Search = () => {
const [query, setQuery] = useState("");
useEffect(() => {
console.log('sendRequest ', query);
}, [query]);
return (
<div>
<input
type="text"
value={query}
placeholder="Search"
onChange={e => {
setQuery(e.target.value);
}}
/>
</div>
}
Upvotes: 1
Reputation: 416
hey bro you can try this implementation its works as you expect
const [query, setQuery] = useState("");
const sendRequest = e => {
setQuery(e);
console.log('sendRequest ', e);
};
return (
<div>
<input
type="text"
value={query}
placeholder="Search"
onChange={e => {
console.log('onChange ', e.target.value);
sendRequest(e.target.value);
}}
/>
</div>)
Upvotes: 1
Reputation: 3270
Use useEffect instead useCallback. useEffect fires your callback function when query changes.
useEffect(() => { console.log(query) }, [query])
Upvotes: 1