拼接和设置状态后奇怪的 return 数据

Weird return of data after splice and setstate

这里用codesandbox模拟

https://codesandbox.io/embed/epic-nash-mxteu?fontsize=14&hidenavigation=1&theme=dark

当我从创建的动态行中删除一行时,我遇到了一个奇怪的行为。

我删除了带有 2 b 的行。如您所见,控制台日志具有正确的数据,而 UI 显示错误的数据。这意味着该功能运行良好但不知何故显示不正确。

有人知道为什么吗?提前致谢

截图

删除行之前

删除行后

源代码

const [gavRows, setGAVRows] = useState([]);

const handleGAVAddRow = async () => {
    try {
        const item = {
            gav_field: '',
            gav_value: ''
        };
        setGAVRows([...gavRows, item]);
    } catch (error) {
        console.log('error', error)
    }
};

const handleGAVRemoveSpecificRow = (idx) => {
    console.log('idx', idx)
    const tempRows = [...gavRows];
    console.log('tempRows', tempRows)
    tempRows.splice(idx, 1);
    setGAVRows(tempRows)
};


const handleGAVChange = async (idx, e) => {
    const { name, value } = e.target;
    var tempRows = [...gavRows];
    tempRows[idx][name] = value;

    setGAVRows(tempRows)
};


<table className="customgav_section">
    <tbody>
        {
            gavRows.map((item, idx) => {
                console.log('map idx', idx, item)
                return (
                    <tr key={idx}>
                        <td>
                            <Input type="text"
                                name="gav_field" id="gav_field"
                                value={gavRows[idx].field}
                                onChange={(e) => handleGAVChange(idx, e)}
                            />
                        </td>
                        <td>
                            <Input type="text"
                                name="gav_value" id="gav_value"
                                value={gavRows[idx].value}
                                onChange={(e) => handleGAVChange(idx, e)}
                            />
                        </td>
                        <td>
                            <Button outline color="danger" onClick={() => handleGAVRemoveSpecificRow(idx)}><FaMinus /></Button>
                        </td>
                    </tr>)
            })
        }
    </tbody>
</table>

你的问题是你使用数组的索引作为键。

阅读为什么不好:https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318

一个快速的 hack 是分配一个随机数作为 gavRows 中每个项目的键,并将其用作元素的键。查看更新后的代码:https://codesandbox.io/s/charming-bouman-03zn7

此外,元素的 id 在 DOM 中必须是唯一的,所以我从 input 元素中删除了它们。

Codesandbox

问题是你输入了错误的值。

记住你设置的项目对象是:

const item = {
  gav_field: "", //not field
  gav_value: ""  //not value
};

您应该修改来自

的代码
<td>
   <Input
     type="text"
     name="gav_field"
     id="gav_field"
     value={gavRows[idx].field}
     onChange={(e) => handleGAVChange(idx, e)}
   />
</td>
<td>
   <Input
      type="text"
      name="gav_value"
      id="gav_value"
      value={gavRows[idx].value}
      onChange={(e) => handleGAVChange(idx, e)}
   />
</td>

收件人:

<td>
   <Input
     type="text"
     name="gav_field"
     id="gav_field"
     value={gavRows[idx].gav_field}
     onChange={(e) => handleGAVChange(idx, e)}
   />
</td>
<td>
   <Input
      type="text"
      name="gav_value"
      id="gav_value"
      value={gavRows[idx].gav_value}
      onChange={(e) => handleGAVChange(idx, e)}
   />
</td>