'setState in useEffect not update
Got an input and want to pass value to handler:
const [term, setTerm] = useState('');
<Input type="text" onBlur={(e)=>handleFilter(e, 'params')} />
const handleFilter = async(e, params) => {
//... api call and etc
setTerm(e.target.value); // update term
console.log(term) // return none-updated value! but I need fresh value
// send this value to another api
}
I want to make an search filter function, for ex. if I enter a, console return empty, then I enter b console return a ! it means term not update immediately, then I used useEffect but inside the useEffect I got new value, but inside handleFilter function still console return prev value.
useEffect(() => {
getApi()
.then(data => {
console.log(data)
})
console.log(term) // works fine, return new value
setTerm(term) // update term
}, [term])
I tried this but no success:
setTerm({...term, e.target.value});
Any solution? I'm new to react hook.
Solution 1:[1]
You can check this answer here.
This is because react's state update is async. You can't rely on its update right after calling setState. Put your effects (code that is run after a state is updated) in a useEffect hook.
const handleFilter = async(e, params) => {
//... api call and etc
setTerm(e.target.value); // update term
}
React.useEffect(() => {
console.log(term) // return none-updated value! but I need fresh value
// send this value to another api
}, [term]);
Solution 2:[2]
setTerm is async and will update the term on the next render cycle.
it is not updated immediately for the current render cycle.
you can store the current value in a ref if you are curious what is happening behind the scenes
const termRef = React.useRef(term);
termRef.current = term;
const yourHandler = () => {
setTimeout(() => console.log(termRef.current), 0);
}
Solution 3:[3]
If we are going ahead with useEffect with an API call, please ensure to include async await scenario to ensure that setState updates after the data is fetched.
useEffect(async () => {
const data = await getApi()
console.log(term) // works fine, return new value
setTerm(term) // update term
}, [term])
Solution 4:[4]
I could be wrong on this one, but could this have something to do with you calling an async function from a normal event. This might cause some type of delay.
There is also the fast that useEffect is treated differently in React than a normal function, since it's integrated into React.
It could also be related to the [term] trigger in the useEffect but the event in your handleFilter isn't treated the same
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | pouria |
| Solution 2 | |
| Solution 3 | Harshith V |
| Solution 4 | OGoodness |
