Sometimes back I was working on a typeahead component that was fetching data from an API and I observed that search query was different from the value in the search field.
After some investigation I realized that this is happening because the setter from the useState
is asynchronous, so fetch is happening before the value is set.
const handleSearch = (e) => {
setQuery(e.target.value);
fetch(`http://example.com/users.json?query=${query}`)
.then(response => response.json())
.then(data => setRecords(data));
}
After some exploration I realized that making a fetch call on the event is the wrong approach, rather we should fetch data as a side effect of the query, which means when the value of query
changes in the component.
@dan_abramov @_developit @mjackson The question is not "when does this effect run" the question is "with which state does this effect synchronize with"
useEffect(fn) // all state
useEffect(fn, []) // no state
useEffect(fn, [these, states])14:14 PM - 05 May 2019
We should use useEffect
to solve this issue. When the value of query
changes useEffect
will fetch data from the API.
const handleSearch = (e) => {
setQuery(e.target.value);
}
useEffect(() = > {
fetch(`http://example.com/users.json?query=${query}`)
.then(response => response.json())
.then(data => setRecords(data));
}, [query]);
In this case, we are setting the value of query
in the event handler and fetch is happening inside the useEffect
block.
For complete solution -
https://gist.github.com/c0d3b1n/469016b05c8020d0b20f130a8bdf94aa
Top comments (0)