reactjs - React 如何更改具有关键属性的组件?
问题描述
我的根组件
import React, {Component} from 'react';
import Task from "./components/task";
class App extends Component {
state = {
keys: [0, 1]
}
changeKeysHandler = () => {
const { keys } = this.state;
const newKeys = keys.slice().reverse();
this.setState({
keys: newKeys
})
}
render() {
return (
<div>
<Task key={this.state.keys[0]}/>
<Task key={this.state.keys[1]}/>
<button onClick={this.changeKeysHandler}>Reverse</button>
</div>
)
}
}
export default App;
我的任务组件
import React, {useState} from "react";
export default function Task() {
const [ value, setValue ] = useState("Tofiq")
return(
<div>
<input
type="text"
value={value}
onChange={(event) => { setValue(event.target.value) }}
/>
</div>
)
}
当我更改键时,React Components 更改命令。但我不明白幕后发生了什么。React 如何与组件相关的关键属性。你能向我解释一下这个植入吗?
解决方案
Akey
是 React 唯一用来识别DOM
元素的东西。
要了解 的工作
key
原理,让我们先了解 React 的行为key
。
假设我们有一个列表
<ul>
<li>first</li>
<li>second</li>
</ul>
默认情况下,当递归一个节点的子DOM
节点时,React 只会同时遍历两个子节点列表,并在有差异时生成一个突变。
例如,当在子节点的末尾添加一个元素时,这两个树之间的转换效果很好:
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
React
将匹配两<li>first</li>
棵树,匹配两<li>second</li>
棵树,然后插入<li>third</li>
树。
在 处插入元素beginning
性能更差。例如,这两个树之间的转换效果不佳,React 会改变每个孩子,而不是意识到它可以保持<li>Duke</li>
和<li>Villanova</li>
子树的完整性。这种低效率可能是一个问题。
钥匙
为了解决这个问题,React 支持一个key
属性。当孩子有 时keys
,React 使用 将key
原始树中的孩子与后续树中的孩子进行匹配。
例如,key
在我们上面的低效示例中添加 a 可以使树转换高效:
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
现在 React 知道带有 key 的元素'2014'
是新元素,带有 key 和 的元素'2015'
是'2016'
刚刚移动的。
现在让我们谈谈你的问题
React 的key
prop 使您能够控制组件实例。每次 React 渲染你的组件时,它都会调用你的函数来检索它用来更新DOM
. 如果您返回相同的元素类型,它会保留这些components/DOM
节点,即使所有 * 道具都已更改。
在您的情况下,组件实例会根据它们的密钥进行更新和重用。在更改key
列表时,诸如不受控制的输入之类的组件状态可能会以意想不到的方式混淆和更新。
推荐阅读
- python - OpenCV:计算椭圆长轴和短轴的方向角
- java - 将列表解析为 Open CSV 中的字符串
- java - 在运行时更改 Tomcat JDBC 池的用户名和密码
- android - 使android上的菜单项像按钮一样工作
- activemq - ActiveMQ 没有正常关闭 -INFO:定期关闭不成功,发送 SIGKILL 到进程
- python - Django中基于日期的自动注销用户
- ios - 我无法添加 locationManager.requestWhenInUseAuthorization()
- r - 为什么传奇标题没有改变?
- programming-languages - 如何使用自动机概念理论制作计算机语言?
- python - 比较两个列表,如果相等则替换第三个列表中的值