form icon indicating copy to clipboard operation
form copied to clipboard

Inconsistent State Movement in React Array Fields on Reordering

Open rodogir opened this issue 1 year ago • 1 comments

Describe the bug

In the field array functionality, when reordering items (e.g. swapping positions, moving items to the top), the underlying values of the array fields change, but the React elements and their associated states do not move accordingly. This results in the states (like counters) sticking to their initial positions rather than moving with their respective items.

Your minimal, reproducible example

https://codesandbox.io/p/devbox/throbbing-bash-9tcy8c

Steps to reproduce

  1. Open the provided CodeSandbox example.
  2. Add multiple items to the hobbies field array.
  3. For any item, increment the counter using the '0' button.
  4. Use the 'swap' or 'move' button to rearrange the order of the items.
  5. Observe the behavior of the counter and the input fields.

Expected behavior

When array items are reordered (either swapped or moved), the state associated with each item (like the counter) should move along with the item. The entire React element representing each item should relocate to reflect the new order, maintaining the integrity of the state and value associations, as seen in the 'list of animals' example included in the CodeSandbox.

How often does this bug happen?

None

Screenshots or Videos

No response

Platform

  • Windows & MacOS
  • Chrome v120

Tanstack Form adapter

react-form

TanStack Form version

0.13.3

TypeScript version

No response

Additional context

One potential solution could be for the library to provide a stable key for each element in the array. This key would be passed as the key prop to the React component representing the array item. @crutchcorn mentioned that there might be an internal id that could be used in this case.

Follow-up of Discord discussion: https://discord.com/channels/719702312431386674/1196808126956052510/1196808126956052510

rodogir avatar Jan 17 '24 13:01 rodogir

There are typescript errors as well. ex. index, field state value is undefined and these come from typescript definitions...

SergiuPlesco avatar Jan 26 '24 19:01 SergiuPlesco

@SergiuPlesco TypeScript errors should be reported elsewhere, but there have been a ton of typing fixes since this was opened, so the issues you experienced may have been solved

crutchcorn avatar Mar 18 '24 08:03 crutchcorn

@rodogir the more I think about this, the more I'm not sure how we could solve this in any meaningful way. From our perspective we shouldn't keep track of an internal key but your data should. We could introduce some kind of keyExtractor or something but even then what would that solve over key={yourIdHere} in React?

I think I'm going to close this for a triage of the upcoming 1.x release, but that doesn't mean the conversation is over. Please keep chatting about the topic and you might convince me that we need to reopen it :)

crutchcorn avatar Mar 18 '24 08:03 crutchcorn

@crutchcorn

The example in the original issue already tries to solve it by managing the key outside the library. See the hobbies fields. In the discord thread I mentioned a potential bug:

I tried adding stable key handling outside of the form to solve it, but it does not work. This is because hobbiesField.state.value only changes on array size changes, not on reordering.

My guess: if hobbiesField.state.value changed on reordering it would solve the problem.

IMO there is no need for the library to keep track of an internal key as long as a solution exists. Currently, the behavior I mentioned is preventing me from handling stable keys.

rodogir avatar Mar 18 '24 16:03 rodogir

Oh! This is an immutability issue, then! 😅 Reopening and tagging @aadito123 who's working on array stuff now

crutchcorn avatar Mar 18 '24 17:03 crutchcorn