gpt4 book ai didi

javascript - 使用 .map 索引作为键时,为什么 React 无法渲染 JSX 元素数组中的更改?

转载 作者:行者123 更新时间:2023-11-28 17:36:47 25 4
gpt4 key购买 nike

里面codepen有一个 React 应用程序可以呈现 ToDo 列表。 它使用 .map() index 参数作为 key 值来呈现此列表。 是的 -我知道这是这种行为的根源,所以请不要在答案中提及这一点。

我在初始加载后添加了一些项目,然后我看到了这个:

enter image description here

然后我按日期对其进行排序,并在第一项中输入一些内容

enter image description here

然后我点击按最新排序并得到:

enter image description here

问题:在此特定示例中使用 .map 索引作为键时,为什么 React 无法呈现 JSX 元素数组中的更改?

附注为了方便起见,这里是代码:

const ToDo = props => (
<tr>
<td>
<label>{props.id}</label>
</td>
<td>
<input />
</td>
<td>
<label>{props.createdAt.toTimeString()}</label>
</td>
</tr>
);

class ToDoList extends React.Component {
constructor() {
super();
const date = new Date();
const todoCounter = 1;
this.state = {
todoCounter: todoCounter,
list: [
{
id: todoCounter,
createdAt: date,
},
],
};
}

sortByEarliest() {
const sortedList = this.state.list.sort((a, b) => {
return a.createdAt - b.createdAt;
});
this.setState({
list: [...sortedList],
});
}

sortByLatest() {
const sortedList = this.state.list.sort((a, b) => {
return b.createdAt - a.createdAt;
});
this.setState({
list: [...sortedList],
});
}

addToEnd() {
const date = new Date();
const nextId = this.state.todoCounter + 1;
const newList = [
...this.state.list,
{id: nextId, createdAt: date},
];
this.setState({
list: newList,
todoCounter: nextId,
});
}

addToStart() {
const date = new Date();
const nextId = this.state.todoCounter + 1;
const newList = [
{id: nextId, createdAt: date},
...this.state.list,
];
this.setState({
list: newList,
todoCounter: nextId,
});
}

render() {
return (
<div>
<code>key=index</code>
<br />
<button onClick={this.addToStart.bind(this)}>
Add New to Start
</button>
<button onClick={this.addToEnd.bind(this)}>
Add New to End
</button>
<button onClick={this.sortByEarliest.bind(this)}>
Sort by Earliest
</button>
<button onClick={this.sortByLatest.bind(this)}>
Sort by Latest
</button>
<table>
<tr>
<th>ID</th>
<th />
<th>created at</th>
</tr>
{this.state.list.map((todo, index) => (
<ToDo key={index} {...todo} />
))}
</table>
</div>
);
}
}

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

最佳答案

似乎输入在这里根本没有改变,并且因为它们不受控制(所以它们的属性/文本值没有改变),这是有道理的,因为根元素在React协调的上下文中没有改变(它有还是一样key)。然后 React 转到最终不同的文本节点,然后仅刷新(更新 DOM)那些已更改的节点。

因此有两种变体可以实现此目的:

  1. 使用有意义的key ,不是index来自.map()
  2. 将(在我们的具体情况下)属性添加到 <input />

一般来说,第一种方法更好,如 key属性将使 root 元素(在我们的例子中是整个 ToDo )无效并强制它呈现自身,从而节省我们对嵌套子树的比较。

关于javascript - 使用 .map 索引作为键时,为什么 React 无法渲染 JSX 元素数组中的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48989969/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com