Reputation: 939
In using useState often I encounter after I use the setter method I want to get the variable and it is not available in my current method directly after setting it and I have to find other ways that are not procedural to use like useEffect.
Sometimes useEffect is not the logical choice b/c the dependency cause code to fire when you don't want to. In the example below I want to setFormData in handleDomainChanges and then in createServices to use it, but was formData was not updated with the latest data. What is the best solution in this case:
const handleDomainsChange = () => {
let filteredArr = listArr.filter(el => el.length > 0)
setFormData({
...formData,
domains: filteredArr,
})
}
const createServices = async () => {
handleDomainsChange()
//** formData is not updated from handlDomainsChange function
const services = await responseCallback('postData', 'services', formData)
services.success && setServices([...services, services.body])
closeServicesModal()
}
I've tried a workaround, which worked but seems not an ideal solution as I have to merge the data with three spread operators:
const handleDomainsChange = () => {
return { domains: listArr.filter(el => el.length > 0) }
}
const editServices = async () => {
const data = handleDomainsChange()
const res = await responseCallback('putData', `services/${formData.PK}`, {
...formData,
...data,
})
if (res.success) {
const updateServices = services.map(service => {
if (service.PK === formData.PK) {
return { ...formData, ...data, service } //*3 spread operators
}
return service
})
setServices(updateServices)
}
Upvotes: 0
Views: 62
Reputation: 1406
Before trying the workaround, Your first case could still work. the problem is that filter will return and array even if its just one element that is returned it will be and array as such, When you do something like
setFormData({
...formData,
domains: filteredArr,
})
it means you are trying to write a mixture of the spread old data of formdata with the array which you obtained from the fitler. You can also just spread the filtered array and it will work just fine as the one you tweaked something like below.
const handleDomainsChange = () => {
let filteredArr = listArr.filter(el => el.length > 0)
setFormData({
...formData,
...filteredArr,
})
}
Upvotes: 1