Reputation: 3
I'm experiencing a big problem with useState and useRecoilState. In particular, I make a call to a rest api with DELETE method, this call returns me a jobId to be able to poll in the future in order to know the status of this job. The call is successful and the response returns correctly, however when I try to set the "ReturnJobId" status it becomes undefined. No console errors or warnings are returned. I've tried using both the react state and the recoil state and they both have the same result. I expect the state to be set correctly as it is a simple string. Below is the offending piece of code. As you can see from the code the variable in question "returnedJobId" is initialized to null but after trying to set it becomes undefined. It is not even a timing problem, I tried to make console log after many seconds and the status still remains undefined. Thanks in advance to anyone who tries to help me
const [returnedJobId, setReturnedJobId] = useState(null);
fetch(basePath + "/digital/cpes/" + cpeToReset + "/redreset", {
method: 'DELETE',
headers: {
federationId: userFederationId
}
}).then(res => res.json())
.then(data => {
console.log("Dati ordine di reset: ", data);
if (data.code !== 200) {
setIsResetting(false);
console.log("Response code errato: ", data.code);
} else {
console.log("Ordine di reset OK");
setReturnedJobId(data.jobId); /*This is the problematic instruction */
console.warn('Setto il seguente job id: ', data.jobId);
setTimeout(() => {
console.log("Stato del job id: ", returnedJobId); /*Here is undefined*/
}, 1000);
}
})
Upvotes: 0
Views: 1692
Reputation: 14355
I'm assuming returnedJobId
is the value corresponding to the setReturnedJobId
state updater. I'm also assuming you're logging the state within a setTimeout
because you're aware that state updates to not take place immediately. The reason you're still having a problem is due to a stale closure.
Notice that if you declared state correctly, returnedJobId
is a const
. A const
cannot change. Even though you've delayed the logging of the variable, it is still a const
and will never be updated.
The way useState
works is by capturing the value of what the new state should be on the next render. In a functional component, the next render corresponds to the next time the functional component is called by React. When any function is called (component or otherwise) all local variables are brand new. The previous render's local variables are destroyed, and new ones are created in their place. useState
is so useful because it assigns that new const
the value you passed to the updater function. It has the illusion of updating the const
, but in reality it is a completely new variable.
So no matter what, you cannot get the new value of state during the current render. You must wait until the next one. The most common way to do this is to use a useEffect
.
useEffect(() => {
console.log("Stato del job id: ", returnedJobId);
}, [returnedJobId]);
Upvotes: 2