了解使用不良反应键的后果

问题描述 投票:0回答:2

最近,我使用数组值而不是像下面这样的键的索引犯了一个小错误:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function NamesView(props: {names: string[], setNames(l: string[]) : void}) {
    const {names, setNames} = props;
    function setName(index: number, name: string) {
        setNames(names.map((n, i) => i===index ? name : names[i]));
    }
    return <div>
        {/***** THE key IS WRONG!!! */ }
        {names.map((n, i) => <input key={n} value={n} onChange={e => setName(i, e.target.value)}/>)}
    </div>;
}

function MainView() {
    const [names, setNames] = useState(() => ['one', 'two']);
    return <NamesView names={names} setNames={setNames}/>
}

ReactDOM.render(<MainView/>, document.getElementById('root'));

在这里,使用key={i}是正确的。我不了解错误代码的行为:每个输入只能编辑一次。您可以添加或删除字符,也可以粘贴某些东西,并且可以使用,但是所有后续更改都会被忽略-直到您更改焦点为止。

有人可以解释为什么吗?

reactjs
2个回答
0
投票

键用于列表,以帮助React识别哪些项目已更改,添加或删除。在您的情况下,您使用名称作为键,因此,每当您更新输入字段的值时,键也会被更新。 React将其检测为被删除的元素,并添加了新元素。

因此,React实际上不只是更新值,而是删除了输入字段,然后再次添加了输入字段,这就是为什么输入在更新其中一个输入之后失去焦点的原因。


0
投票

当通过names映射时,这是输入值的数组。您正在通过以下方式呈现输入。

return (
  <div>
    {/***** THE key IS WRONG!!! */}
    {names.map((n, i) => (
      <input key={n} value={n} onChange={(e) => setName(i, e.target.value)} />
    ))}
  </div>
);

一旦更改输入,setNames就会通过setName通过onChange触发。

这意味着react现在将检查生成的新项目。

因为key={n}会更改输入本身,即会在dom中生成一个新的输入元素并立即对其进行更新,这就是为什么每次更改它都会失去焦点。

您可以在这里阅读有关键的更多信息:

  1. https://reactjs.org/docs/lists-and-keys.html
  2. https://reactjs.org/docs/reconciliation.html#recursing-on-children
© www.soinside.com 2019 - 2024. All rights reserved.