Chr*_*ris 8 javascript reactjs
我最近发表了一个问题的答案,当我key从数组返回时发现了一个问题.
我已经知道,兄弟组件中的键必须是唯一的.这在官方的React文档中说明,这里:
数组中使用的键在其兄弟姐妹中应该是唯一的.但是,它们不需要是全球唯一的.当我们生成两个不同的数组时,我们可以使用相同的键.
但是,与上面的粗体文本相比,似乎React对于相同的数组具有相同的键是很好的.为什么下面的代码片段工作且密钥不会发生冲突?
class MyApp extends React.Component {
renderArray = () => {
return [
<p key={0}>Foo</p>,
<p key={1}>Bar</p>,
<p key={2}>Baz</p>
];
}
render() {
return (
<div>
{this.renderArray()}
{this.renderArray()}
{this.renderArray()}
</div>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>Run Code Online (Sandbox Code Playgroud)
显然,这不起作用:
class MyApp extends React.Component {
render() {
return (
<div>
<p key={0}>Foo</p>
<p key={1}>Bar</p>
<p key={2}>Baz</p>
<p key={0}>Foo</p>
<p key={1}>Bar</p>
<p key={2}>Baz</p>
<p key={0}>Foo</p>
<p key={1}>Bar</p>
<p key={2}>Baz</p>
</div>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("app"));Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>Run Code Online (Sandbox Code Playgroud)
所以我的问题是,为什么第一个片段工作但不是第二个?似乎他们都应该产生完全相同的结果?
答案列出了createHierarchyRenderer方法/功能的工作原理.源createHierarchyRenderer.js
它是reducingRight并通过渲染将组件附加到查询结果中.
它创建的renderHierarchy是2d组件数组,因此......您的renderArray调用在层次结构中具有不同的索引,这使得它们的层次结构彼此独立.
第二种情况不起作用,因为密钥是伪层次结构以提高性能 - 你可以不用键控地执行此操作,但是 - 对于更大的渲染队列来说这是非常糟糕的做法.因此,传递键 - 覆盖由...表示的维度key.
为什么没有传递密钥就能工作?哪个键最好?如何提高?!
来源:
Run Code Online (Sandbox Code Playgroud)/** * Generate a key string that identifies a component within a set. * * @param {*} component A component that could contain a manual key. * @param {number} index Index that is used if a manual key is not provided. * @return {string} */ function getComponentKey(component, index) { // Do some typechecking here since we call this blindly. We want to ensure // that we don't block potential future ES APIs. if (component && typeof component === 'object' && component.key != null) { // Explicit key return KeyEscapeUtils.escape(component.key); } // Implicit key determined by the index in the set return index.toString(36); }
此方法由traverseStackChildrenImpl同一文件中的方法调用.如果你要深入研究这些魔法:
Run Code Online (Sandbox Code Playgroud)for (var i = 0; i < children.length; i++) { child = children[i]; nextName = nextNamePrefix + getComponentKey(child, i); subtreeCount += traverseStackChildrenImpl( child, nextName, callback, traverseContext, ); }
你会明白它为什么会起作用,你会知道为什么没有键的键控工作,以及你的性能损失.传递key但很好... React可以为我们自动传递索引,key旨在获取id组件创建者对象...例如:
users.map((v, i) => (<UserItem data={v} key={i} />)
Run Code Online (Sandbox Code Playgroud)
没有通过key,但没有区别,但它被认为是一个不好的做法:
users.map((v, i) => (<UserItem data={v} />)
Run Code Online (Sandbox Code Playgroud)
keymagic是为了在用fe附加数组的情况下使用户的id不重新渲染其他用户.users = users.unshift(someuser).最好的设置是:
users.map((v, i) => (<UserItem data={v} key={v.userId} />)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
342 次 |
| 最近记录: |