inertia icon indicating copy to clipboard operation
inertia copied to clipboard

When making consecutive calls to setData, only the last call will work

Open aviemet opened this issue 3 years ago • 4 comments

Versions:

  • @inertiajs/inertia version: 0.11.0
  • @inertiajs/inertia-react version: 0.8.0

Describe the problem:

When making consecutive calls to setData from the useForm hook, no values are set on the data object.

Steps to reproduce:

I was essentially trying to have a section of a form which populated values if it was shown, but removed them from the data object upon hiding so they aren't include in a form submission. The following is a very contrived example, but should reproduce the issue:

const [showThing, setShowThing] = useState(false)

const { data, setData } = useForm({
  thingOne: undefined,
  thingTwo: undefined,
  thingThree: undefined
})

useEffect(() => {
  if(showThing) {
    setData('thingOne', 'something')
    setData('thingTwo', 'not nothing')
    setData('thingThree', 'words')
  }
}, [showThing])

return <input type="checkbox" checked={ showThing } onChange={ e => setShowThing(e.target.checked) } />

The elements thingOne and thingTwo never change, only thingThree will get assigned the value 'words'.

I eventually realized that I could set values on the data object by passing an object. I'm assuming there's some kind of debounce happening to avoid some renders, so it would be nice to have it documented somewhere that there are multiple acceptable call signatures for setData, the docs only show how to use it with two parameters.

aviemet avatar Feb 05 '22 00:02 aviemet

you can try

setData({
  thingOne: 'something',
  thingTwo: 'not nothing',
  thingThree: 'words'
})

muh-hizbe avatar Apr 08 '22 14:04 muh-hizbe

To setData in a row

setData(data => ({ ...data, thingOne: 'something'}));
setData(data => ({ ...data, thingTwo: 'not nothing'}));
setData(data => ({ ...data, thingThree: 'words'}));

I faced this same problem

shimulsql avatar Jun 06 '22 18:06 shimulsql

you can try

setData({
  thingOne: 'something',
  thingTwo: 'not nothing',
  thingThree: 'words'
})

It won't work. You have to pass a callback function instead of object.

shimulsql avatar Jun 07 '22 06:06 shimulsql

other solutions in this thread overwrite all data.

use this to REPLACE certain data by keys, e.g.:

        const address = "123 test st, Toronto, ON".split(', ');
        const newData = {
            address: address[0],
            city: address[1],
            province: address[2],
        }

        setData({ ...data, ...newData });

jaxramus avatar Jun 27 '22 10:06 jaxramus

This happened to me too on the new inertiajs/inertia v1.0. I would just like to understand why the setData function behaves that way.

iramikken avatar Apr 12 '23 08:04 iramikken

So apparently, this is not a bug but due to the behavior of state in React

iramikken avatar Apr 19 '23 09:04 iramikken

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️

reinink avatar Jul 28 '23 01:07 reinink

This one was fixed in #1859

derrickreimer avatar Jun 24 '24 14:06 derrickreimer