React renders the wrong data when deleting the item in the middle of the list

1.4k views Asked by At

I've got a nested field arrays setup use react-hook-form here. Take note that my actual code is a bit more complex, but the issue is displayed here just the same.

enter image description here

The issue I have is that if I delete an item in the list, say, ID: 2 in list [{ID:1}, {ID:2}, {ID:3}], the result isn't [{ID:1}, {ID:3}], but instead, [{ID:1}, {ID:2}].

Here's the official example, which gets nested fields array right.

Near as I can tell, the only difference is that my form relies on data that is retrieved from an API (in my example, handled by an async function) whereas the official example uses data that's already been initiated.

Looking at samples online, some make use of the <Controller> field, but that just gave me more issues (in my actual code), and upon testing (in Code Sandbox), doesn't really change the fact that deleting 2 doesn't shift the entire array up.

Is there anything I'm missing?

1

There are 1 answers

0
NearHuscarl On BEST ANSWER

You should not pass array index as key to each child in a list of children. Here is the problematic code:

{fields.map((task, j) => {
  return (
    <Box key={j} padding={2} border={1}>
      {...}
    </Box>
  );
})}

When you run the code above, you'll have children with the corresponding data array like this

{ key: 0, task: { id: "1", freq: "d" },
{ key: 1, task: { id: "2", freq: "d" },
{ key: 2, task: { id: "3", freq: "d" },

If you delete the first item, in the next render, the data array will look like this

{ key: 0, task: { id: "2", freq: "d" },
{ key: 1, task: { id: "3", freq: "d" },

This is because the first item where task.id = 1 was deleted, but the index of the array still starts from 0, so in the end there is a mismatch between key and task.id.

The best way to fix this problem is to use a unique ID directly from your model instead of array index as key:

{fields.map((task, j) => {
  return (
    <Box key={task.id} padding={2} border={1}>
      {...}
    </Box>
  );
})}

Live Demo

Edit 64244731/react-hook-form-nested-fieldarray-deleting-item-in-the-middle-of-the-list-does