'State in useEffect undefined after the useEffect sets the state?
I have a React Native app in which I am running some code that looks like the code below. Why is the following output undefined
? Reading someState
from useEffect
is undefined
even when the state is set inside the useEffect
const SomeComponent = () => {
const [someState,setSomeState] = useState();
const anFunction = () => {
let data = 'data'
return data
}
useEffect(() => {
const theData = anFunction();
setSomeState(theData)
console.log(someState)
},[])
...
// later renders some component
}
I am attempting set the state and then read the state within this useEffect
because I would like to implement something like:
const doSomethingWithTheState = () => {
//some transformation here
setSomeState(transformedData)
}
useEffect(() => {
const theData = anFunction();
setSomeState(theData)
doSomethingWithTheState()
},[])
Solution 1:[1]
You might get something out of my answer to a similar question: React Native I can not store an array with AsyncStorage
@gloo posted a much more interesting discussion on this issue here: The useState set method is not reflecting a change immediately
Setting state is neither sync nor async. It's a quirk/feature of the React ecosystem. State is immutable in terms of a single render; therefore you'll never get the updated state until the next render.
If you need to work with the state directly after it's been changed, do it in a useEffect with the state variable in the dependency array.
Solution 2:[2]
It should work by adding a .then
.then(doSomethingWithTheState())
Solution 3:[3]
It is undefined because useEffect
is not async
. Your initial state is already undefined
so you see undefined
in console.log
. To create async logic inside useEffect
you should update like this
useEffect(() => {
async function test(){
//Your logic here
}
test()
},[])
Solution 4:[4]
Because my goal is to mutate the data within the useEffect
it was better to initialize my state using the anFunction()
(obviously this is still just an example). Here's what my code looks like now:
const SomeComponent = () => {
const [someState,setSomeState] = useState(anFunction());
const anFunction = () => {
let data = 'data'
return data
}
useEffect(() => {
console.log(someState)
},[])
...
// later renders some component
}
I've seen of conversation about how useState is async. This is misleading. Looking at Abe's answer and his description will guide you towards resolving many weird React state-setting behaviors.
Do not try to await
or async
your state setting within the useEffect
.
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 | |
Solution 2 | |
Solution 3 | Evren |
Solution 4 | patataskr |