React为单选按钮(在地图中)提供唯一的密钥警告,忽略所提供的唯一密钥



我有以下代码(显然这只是一个问题的测试用例,生活更复杂…(。此代码有效,但它给出了警告:

数组或迭代器中的每个子级都应该有一个唯一的"键"道具。

我对React和javascript很陌生,但我确实理解错误也确实理解为什么需要唯一密钥。正如你所看到的,我确实提供了钥匙,它们确实是独一无二的

var possible_variants = ["A", "B", "C"];
var variant = "";
class App extends React.Component {
render() {
return React.createElement(
"div",
null,
React.createElement(RadioButton, null)
);
}
}
class RadioButton extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
variant = event.target.value;
}
render() {
return React.createElement(
"div",
{
onChange: this.handleChange
},
possible_variants.map(function(my_variant, index) {
return React.createElement(
"label",
null,
React.createElement("input", {
type: "radio",
value: my_variant,
key: my_variant,
name: "variant"
}),
my_variant
);
})
);
}
}
ReactDOM.render(
React.createElement(App, null),
document.getElementById("container")
);

问题似乎是React"希望"密钥在包装标签中,即如果我将映射更改为

possible_variants.map(function(my_variant, index) {
return React.createElement(
"label",
{
key: my_variant // <= here comes the difference
},
React.createElement("input", {
type: "radio",
value: my_variant,
name: "variant"
}),
my_variant
);
});

警告消失了。

所以我的问题是为什么会这样?我从官方文档和网络上的各种教程中了解到,为了获得最佳性能,人们希望关键是最具体的东西,这些东西可能会因重新渲染而改变,这就是这里的输入,而不是一劳永逸的标签。

我是不是错过了什么?

PS:对我来说,这感觉类似于映射警告时的React唯一密钥

首先,我们都知道,需要一个唯一的密钥。

至于代码,第一个代码实际上没有进行键绑定来映射项,而第二个代码则进行了绑定。

请参阅React.createElement文档,每个文档创建一个级别的DOM元素。

在您的第一个代码中,它实际上创建了两次,这意味着您的密钥只绑定在map items内部,list.map下的map items没有任何密钥。

<label>
<input key={...}/>
</label>

第二个让它变得正常,所以它有区别。

<label key={...}>
<input />
</label>

顺便说一句,正如评论所说,你很少有机会使用那些reacttop-level API,JSX/TSX只是让它更简单。

具体的相关QA。

最新更新