react源码中那些小而美函数之warnForMissingKey

74 阅读2分钟
warnForMissingKey = function (child, returnFiber) {
      if (child === null || typeof child !== 'object') {
        return;
      }

      if (!child._store || child._store.validated || child.key != null) {
        return;
      }

      if (typeof child._store !== 'object') {
        throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.');
      }

      child._store.validated = true;
      var componentName = getComponentNameFromFiber(returnFiber) || 'Component';

      if (ownerHasKeyUseWarning[componentName]) {
        return;
      }

      ownerHasKeyUseWarning[componentName] = true;

      error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
    };
  }

这段代码是 React 源码中的一部分,用于检测 React 组件树中子组件是否设置了唯一的 "key" 属性。在 React 中,使用列表渲染子组件时,每个子组件都应该有一个唯一的 "key" 属性,以便 React 可以有效地管理组件的状态和更新。

让我简要解释一下这个函数的逻辑:

  1. 首先,检查传入的子组件 child 是否为对象且不为 null。如果不是对象或为 null,则直接返回,因为无法为非对象或 null 的子组件生成 key。

  2. 然后,检查子组件是否已经有了 key。如果已经有 key,或者子组件的 _store 属性不存在或已经经过验证,那么直接返回,不做任何操作。

  3. 如果子组件的 _store 不是对象,抛出错误。这是一个异常情况,表示 React 组件在 warnForMissingKey 函数中应该有一个 _store 属性。

  4. 将子组件的 _store.validated 属性设置为 true,表示已经进行了验证。

  5. 获取父组件的名称,如果获取不到,则使用默认值 'Component'。

  6. 检查是否已经对当前父组件的名称发出过警告。如果发出过警告,则直接返回,避免重复警告。

  7. 标记当前父组件的名称已经发出过警告。

  8. 使用 error 函数输出警告信息,提示开发者每个列表中的子组件都应该有唯一的 "key" 属性。

这个函数的作用是在开发环境下,帮助开发者发现并修复没有设置 "key" 属性的情况,以避免在 React 中出现不稳定的列表渲染行为。