Is there a stable identifier for array fields?
I've been playing around with the library and liking it very much so far. I was surprised that to docs use the array index as key. See https://tanstack.com/form/latest/docs/guides/basic-concepts#array-fields
I wanted to to add a drag-and-drop reordering to my array fields but without a stable identifier it's almost impossible. So here are my questions:
- Is there an undocumented stable field identifier?
- If not, are there plans to add one?
I can also solve this problem outside of the library by making the
key
part of the form value. Though I think handling this within the library would be great.Basic Concepts and Terminology | TanStack Form Docs
This page introduces the basic concepts and terminology used in the @tanstack/react-form library. Familiarizing yourself with these concepts will help you better understand and work with the library.
Form Factory
7 Replies
ambitious-aqua•2y ago
I'm not sure that's a good idea, because to be able to manage the array items, you need to be able to identify them, so it's on you to define unique ids. Otherwise all of the libraries would handle that out of the box and we wouldn't need to define our own keys inside an array.
You can use a library for that, something like uuid
like-goldOP•2y ago
Thanks, I understand the reasoning. Then I will solve it in user-land.
I've used other libraries in the past that had that feature built-in, that's why I asked.
ambitious-aqua•2y ago
Yes, you can either add it to the objects used to define the array, or like you said, include it in the form, that also makes sense when you are editing the existing resource, so you will probably need an id to be able to update the data on the server
like-goldOP•2y ago
I need to reopen this discussion. After testing the field array functionality a bit more I noticed that the current behavior might be problematic. I created a example to showcase the problem: https://codesandbox.io/p/devbox/throbbing-bash-9tcy8c
I added the array fields example from the docs and added two buttons to each element: swap (swaps position with top item) and move (moves item to the top).
If you only look at the rendered output everything looks fine but here is what I observed:
- The individual array fields are not moved, instead the underlying values change. What I mean by that: the DOM nodes are not moved, instead the individual input fields whose values were changed simply rerender with their new value.
I feel this is problematic as any state sticks to its initial position instead of moving with its item. To illustrate that I added a third button
0
. It's a simple counter that when clicked increments by one. In the hobbies, if I add some hobbies and then change a counter and then press the swap or move button you will see the values change, but the counter stays.
The expected behavior is illustrated by the list of animals below the form. The counter will move when the array order is changed.
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.
@crutchcorn what do you think of my findings? It this expected? If not, I can create an issue for it.extended-salmon•2y ago
I think we may have an internal id that's created that you could use
But I dunno know it off the top 😅 Let's create an issue for sure. Good work on your findings!
like-goldOP•2y ago
Issue created: https://github.com/TanStack/form/issues/573
GitHub
Inconsistent State Movement in React Array Fields on Reordering · I...
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...
sensitive-blue•2y ago
@crutchcorn in the sandbox linked in this issue that was created: the inner array fields, for example, line 117, they are not getting the type for the name and index. Is that a separate issue? I tried building a similar form locally, and I also get an error about multiple Field setters being used at the same time when an input changes