最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React renders the wrong data when deleting the item in the middle of the list - Stack Overflow

programmeradmin8浏览0评论

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 badges
Add a ment  | 

1 Answer 1

Reset to default 10

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

发布评论

评论列表(0)

  1. 暂无评论