我注意到我可以传递给React一组嵌套数组并且它会正确地渲染项目,但是当我这样做时,它不会抱怨我的元素上缺少worker.execute(job)
。
key
样品笔:
https://codepen.io/FezVrasta/pen/NppLPR
为什么会这样?我无法找到对#34;嵌套数组的任何引用"在React中支持,既不在"自动分配键"。
答案 0 :(得分:4)
您会注意到即使向控制台打印了警告,React仍然会在您生成的HTML中显示Foo
和Bar
。 React使用唯一键进行对帐,同时尝试提高渲染性能。您可以在React reconciliation recursing on children页面上详细了解相关信息。不提供密钥意味着React不能像它设计的那样具有高性能。
关于为什么没有向嵌套数组的控制台输出警告的问题,我们必须深入研究源代码:
生成警告的函数称为validateExplicitKey
,并存在于ReactElementValidator.js
模块中。
此函数在同一模块的validateChildKeys
中使用 - 查看源代码给出以下内容,从React 15.4.2开始:
function validateChildKeys(node, parentType) {
if (typeof node !== 'object') {
return;
}
if (Array.isArray(node)) { // 1.
for (var i = 0; i < node.length; i++) {
var child = node[i]; // 2.
if (ReactElement.isValidElement(child)) { // 3.
validateExplicitKey(child, parentType);
}
}
} else if (ReactElement.isValidElement(node)) {
// This element was passed in a valid location.
if (node._store) {
node._store.validated = true;
}
} else if (node) {
var iteratorFn = getIteratorFn(node);
// Entry iterators provide implicit keys.
if (iteratorFn) {
if (iteratorFn !== node.entries) {
var iterator = iteratorFn.call(node);
var step;
while (!(step = iterator.next()).done) {
if (ReactElement.isValidElement(step.value)) {
validateExplicitKey(step.value, parentType);
}
}
}
}
}
}
child
将被设置为child = ["b", Object]
(其中'Object'是我们通过JSX创建的br
节点的反应虚拟dom表示形式)数组将通过函数ReactElement.isValidElement
:
ReactElement.isValidElement = function (object) {
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
};
将REACT_ELEMENT_TYPE
设置为:
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
数组是一个对象,不是null
,但是这里没有设置$$typeof
属性,因此检查失败。
$$typeof
尚未设置,因为React仅将此属性添加到它创建的元素,以识别某些内容是否为React元素。这包括原生HTML元素,而不是数据类型。
因此ReactElement.isValidElement
检查失败,并且永远不会显示警告。
答案 1 :(得分:1)
我最近也想知道同样的事情!
根据我在ReactJS关于how the key
s work的官方文档中所理解的内容,我希望通过嵌套数据数组得到相同的警告,就像具有 flat 数据数组的那个,因为在这两种情况下都没有设置关键属性。
键帮助React识别哪些项目已更改,已添加或已删除。键应该被赋予数组中的元素,以赋予元素稳定的标识。
我实际上填写了一个bug report (issue) in the ReactJS official GitHub repo,描述了您指出的相同案例,但已经简化(没有花哨的.map()
和.reduce()
件事。)
对我来说,它看起来像 bug 。
PS:一旦React团队回复我,我会立即更新我的答案。