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.
CodePudding user response:
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
CodePudding user response:
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]);
CodePudding user response:
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);
}
CodePudding user response:
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])