Javascript 我们必须为哪些位置和哪些元素提供唯一的密钥?
我一直认为唯一需要唯一键的地方是Javascript 我们必须为哪些位置和哪些元素提供唯一的密钥?,javascript,reactjs,Javascript,Reactjs,我一直认为唯一需要唯一键的地方是列表和数组中,比如映射,但今天我正在为我的组件编写一个加载屏幕,以便向用户显示加载,加载结束后,我会进行设置状态,并让渲染人员知道是时候渲染真实视图了。 但是我看到新组件没有被渲染,加载仍然在屏幕上!经过大量测试,我看到一切正常,最后我想让我们给它一把钥匙,也许会发生什么事!!它做到了!,问题解决了,我很困惑,到底为什么那里需要钥匙 下面是我所做的和所发生的事情的sudo代码: render () { //with no key, this doesn't r
列表
和数组
中,比如映射
,但今天我正在为我的组件编写一个加载屏幕,以便向用户显示加载,加载结束后,我会进行设置状态,并让渲染人员知道是时候渲染真实视图了。但是我看到新组件没有被渲染,加载仍然在屏幕上!经过大量测试,我看到一切正常,最后我想让我们给它一把钥匙,也许会发生什么事!!它做到了!,问题解决了,我很困惑,到底为什么那里需要钥匙
下面是我所做的和所发生的事情的sudo代码:
render () {
//with no key, this doesn't render properly
const finalView = this.state.isLoading ?
<UIManager key={1} json= {myLoadingComponentJSON} />
:
<UIManager key={2} json={myFormJson} />;
return () {
finalView
}
}
render(){
//如果没有关键点,则无法正确渲染
const finalView=this.state.isLoading?
:
;
返回(){
最终视图
}
}
我可以大胆地看到,这里的问题可能是我正在使用一个名为UIManager
的组件,我使用一个JSON
来知道这个组件应该呈现什么样的元素,而且可能两个UIManager都有相同的键?嗯,我不确定,但我仍然认为这里不需要钥匙
我们必须为哪些位置和哪些元素提供唯一的密钥
仅为您希望重新排序项目的同级提供键
(想想列表项目)
如果孩子是唯一的(即没有兄弟姐妹),则不需要键
键
在具有相同祖先的兄弟姐妹之间应该是唯一的
因此,对于UIManager
,您可以提供一个名称作为键
i、 e
const finalView=this.state.isLoading?
:
;
为什么?
真正的原因是反应如何。如果没有键
,React只会查看json
属性,并检查其是否更改(对于嵌套较深的json数据,可能存在性能问题-帧变慢/丢失)。如果在json
中看到任何更改,它将销毁以前的UIManager
实例
看
摘要:
通过提供一个
键
,可以更轻松地检查差异。对账
React提供了一个声明式API,这样您就不必担心每次更新都会发生什么变化。这使得编写应用程序变得更加容易,但在React中如何实现这一点可能并不明显。本文解释了我们在React的“diffing”算法中所做的选择,以使组件更新可以预测,同时对高性能应用程序来说速度足够快
因为如果不满足React背后的假设,React依赖于启发式,因此性能将受到影响
- 该算法不会尝试匹配不同类型的子树 组件类型。如果你看到自己在两个组件之间交替 具有非常相似输出的类型,您可能希望使其成为相同的类型。 实际上,我们还没有发现这是一个问题
- 密钥应该是稳定的、可预测的和唯一的。不稳定键(如 由Math.random()生成的组件将导致许多组件实例 不必要地重新创建DOM节点,这可能导致 子组件中的性能降级和状态丢失
UIManager
,因此react无法确定渲染哪个组件,这是其背后的主要原因
它在设定键后工作
当您设置key react时,将它们标识为不同的组件,尽管您可以尝试以下方法
render () {
const finalView =
<UIManager json= { this.state.isLoading ? myLoadingComponentJSON : myFormJson} /> ;
return () {
finalView
}
}
render(){
const finalView=
;
返回(){
最终视图
}
}
如果没有键的代码没有呈现this.state.isLoading
设置为false之后的第二个组件,那么这里发生了与键无关的其他事情。@ChrisG,发生的事情正是您描述的,既然给它一个键
修复了它,它怎么可能与键
无关呢!?好问题,但是
render () {
const finalView =
<UIManager json= { this.state.isLoading ? myLoadingComponentJSON : myFormJson} /> ;
return () {
finalView
}
}