React Hooks Callback Receives Outdated State
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.
Answer
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>
}
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM