I've got a nested field arrays setup use react-hook-form
here. Take note that my actual code is a bit more plex, but the issue is displayed here just the same.
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?
I've got a nested field arrays setup use react-hook-form
here. Take note that my actual code is a bit more plex, but the issue is displayed here just the same.
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?
Share Improve this question edited Oct 8, 2020 at 4:31 NearHuscarl 82.1k23 gold badges320 silver badges282 bronze badges asked Oct 7, 2020 at 13:11 zack_falconzack_falcon 4,38623 gold badges68 silver badges111 bronze badges1 Answer
Reset to default 10You 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>
);
})}