Reputation: 8297
<Button
onClick={() => {
console.log('addedNodes', addedNodes)
let credentials = //something...
let nodes = [...addedNodes]
console.log(addedNodes)
setCurrentForm(
{
...currentForm,
credentials: credentials,
nodes: [...addedNodes],
}
)
}}
</Button>
I have a button that updates the currentForm
state using another state addedNodes
.
Whenever the currentForm
gets updated, I console.log the currentForm
using useEffect
.
useEffect(() => {
console.log('currentForm ,,,,,, ', currentForm)
console.log('addedNodes ,,,,,, ', addedNodes)
}, [currentForm]);
This prints out the CORRECT updated state.
However, when I try to add an API request using that state, it goes back to the state before it got updated.
For example, when I update my useEffect
to
useEffect(() => {
console.log('currentForm,,,,,, ', currentForm)
console.log('addedNodes ,,,,,, ', addedNodes)
console.log('RUNNING POST')
setLoadingStatus('loading')
let body = {
form: currentForm,
}
intializeForms()
let options = {
headers: header,
method: 'post',
mode: 'cors',
body: JSON.stringify(body),
}
console.log('options.body', options.body)
const urls = ['...'];
const fetchJson = url => fetch(url, options).then(res => res.json());
Promise.all(urls.map(fetchJson))
.then(([result]) => {
...
})
.catch(err => {
setLoadingStatus('none')
console.log(err)
});
}, [currentForm]);
The console.log('options.body', options.body)
prints out the old currentForm
.
This is very weird to be because console.log(currentForm)
prints the expected state, but when I actually use it for an API call, it goes back to the original form.
I assume that it is because this useEffect
gets called everytime the state gets updated, but not really sure.
Any help, please?
Upvotes: 0
Views: 86
Reputation: 8418
Problematic code fragment
let body = { form: currentForm, } intializeForms() // later bad body.form content
form
gets a reference to currentFrom
object then currentFrom
is overwritten in intializeForms()
... this way JSON.stringify(body)
operates on bad data.
Why Kaca992's solution didn't worked?
let body = { form: {...currentForm}, }
It should create a fresh object from currentForm
' element/properties.
Probably it worked for some part of currentForm
, f.e. for nodes
as they was properly (in immutable way - by new instance) assigned/passed:
nodes: [...addedNodes],
Probably other currentForm
elements are a copies of always the same object references, mutated on changes, not replaced with new instances.
In this case it's enough to call intializeForms()
just after currentForm
"consuming" (stringify) - let options =
block.
Other good place for form reset (intializeForms()
call) can be Promise.all(...
resolving function (.then
part).
Upvotes: 1
Reputation: 2267
What does initializeForms do? If currentForms is a reference type maybe you reset the value? Try setting the body like this:
let body = {
form: {...currentForm},
}
Upvotes: 0