React中的Flat Array与嵌套数组的处理方式不同

时间:2017-03-10 17:30:56

标签: javascript arrays reactjs

我注意到我可以传递给React一组嵌套数组并且它会正确地渲染项目,但是当我这样做时,它不会抱怨我的元素上缺少worker.execute(job)

key

样品笔:

https://codepen.io/FezVrasta/pen/NppLPR

为什么会这样?我无法找到对#34;嵌套数组的任何引用"在React中支持,既不在"自动分配键"。

2 个答案:

答案 0 :(得分:4)

您会注意到即使向控制台打印了警告,React仍然会在您生成的HTML中显示FooBar。 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);
          }
        }
      }
    }
  }
}
  1. 数组数组将进入第一个代码块
  2. child将被设置为child = ["b", Object](其中'Object'是我们通过JSX创建的br节点的反应虚拟dom表示形式)
  3. 数组将通过函数ReactElement.isValidElement

    运行
    ReactElement.isValidElement = function (object) {
      return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
    };
    
  4. 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 keys work的官方文档中所理解的内容,我希望通过嵌套数据数组得到相同的警告,就像具有 flat 数据数组的那个,因为在这两种情况下都没有设置关键属性。

  

键帮助React识别哪些项目已更改,已添加或已删除。键应该被赋予数组中的元素,以赋予元素稳定的标识。

我实际上填写了一个bug report (issue) in the ReactJS official GitHub repo,描述了您指出的相同案例,但已经简化(没有花哨的.map().reduce()件事。)

对我来说,它看起来像 bug

PS:一旦React团队回复我,我会立即更新我的答案。

相关问题