昨天我们介绍了 key 的基本使用方式,今天我们就一起来了解为什麽需要 key 吧!
首先,在了解为什麽之需要 key 之前,要先知道 React 在每一次的 state 更新都会触发 re-render , render 完之後会比较当次与前一次 Virtual DOM 的差异(Diff 演算),最後才会去更新 DOM 。
知道每一次 re-render 都会都会比较差异後,我们就来沙盘推演一下,在没有设置 key 的情况,React 会去怎麽做。
假设一开始我们有一个五个 li
<ul>
<li>red</li>
<li>blue</li>
<li>yellow</li>
<li>green</li>
<li>purple</li>
</ul>
<ul>
<li>red</li>
<li>blue</li>
<li>yellow</li>
<li>green</li>
</ul>
我们从头开始比对,比较跟前一次的差异,发现最後一个 purple 不见了,
所以我们找出前後两者个差异就是
- <li>purple</li>
<ul>
<li>blue</li>
<li>yellow</li>
<li>green</li>
</ul>
然後一样跟前一次比对,这个时候就会发现
前一次 新的
<ul> <ul>
<li>red</li> -> <li>blue</li>
<li>blue</li> -> <li>yellow</li>
<li>yellow</li> -> <li>green</li>
<li>green</li> ->
</ul> </ul>
结果就会变成:
- <li>red</li>
- <li>blue</li>
- <li>yellow</li>
- <li>green</li>
+ <li>blue</li>
+ <li>yellow</li>
+ <li>green</li>
可以仔细观察一下旁边 Elements 的变化
从我们上面的范例可以得知,React 其实没办法准确的知道使用者是删除或修改哪一个 item,但它还是必须去执行,所以这个时候,就会把 index 作为 key 来执行,这也就是为什麽不建议使用阵列的 index 作为 key 的关系。
除了效能之外,当元素有 uncontrolled component 时会造成非预期的渲染。
<html lang="en">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='root'></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/[email protected]/babel.js"></script>
<script type='text/babel'>
function App() {
const [colors, setColors] = React.useState([
'red',
'blue',
'yellow',
'green',
'purple'
])
const removeItem = (targetItem) => {
setColors((prev) => prev.filter(item => item != targetItem))
}
return (
<ul>
{colors.map((item, idx) => {
return (
<li>
<button onClick={() => { removeItem(item) }}>x</button>
<input type="text" defaultValue={item} />
{item}
</li>
)
})}
</ul>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</body>
可以发现 input 的 value 并不是交给 React 来管理,所以当我们删除第一个 li 时,其实是将 red 修改成 blue , input 的 defalutValue 也确实有改,但 value 的 state 本身是交给 Html form element 管理,input 并没有整个换掉,所以 value 依然保持 red。
所以当我们在 render list 的时候要特别注意这个 list 会不会做修改,或是有没有用到 uncontrolled component ,如果有那就不能使用 index 作为 key。
当然如果不想思考这麽多,其实只要确保在 render list 都给唯一的 key 就不会有什麽问题了。
以上就是今天的介绍,有什麽问题都欢迎在下方留言。
参考资料:
https://epicreact.dev/why-react-needs-a-key-prop/
今天要来介绍的是 NiFi Expression Language (以下简称NEL)。在前一篇我们...
今天是最後一天,咱们今天不看程序码,来谈谈现在我们已经学习了 JavaScript,做个总结顺便想想...
这篇主要讲GetX在页面切换之间的路由(上下页的前後文关系) 初步先建立一个routes的资料夹 里...
注册 Azure 帐号与套件安装- 免费体验30天 基本起手式,能注册的先注册,能安装的先安装。 注...
到目前为止,我试玩过 CC: Tweaked Disk Drive、Speaker、Printer、...