使用 React.Children.map 时,React 会自动处理键吗?

IT技术 javascript reactjs
2021-05-25 18:36:57

我很清楚在 React 中创建动态子项时需要添加prop原因key令我感兴趣的是以下两段代码的行为

children仅使用Array#map 进行迭代

const App = () => {
  return (
    <Parent>
      <span>Child 1</span>
      <span>Child 2</span>
      <span>Child 3</span>
    </Parent>
  );
};

const Parent = ({ children }) => {
  return children.map(child => (
    <div style={{ background: "lightblue" }}>{child}</div>
  ));
};
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id="app">

这用于React.Children.map做同样的事情

第一个片段产生警告

数组或迭代器中的每个孩子都应该有一个唯一的“key” prop

而第二个不产生任何。所以我的两个问题是:

  1. 是否React.Children.map为我们通过它的元素自动生成键?
  2. 如果上述问题的答案是肯定的,那么它是否保证密钥在重新渲染时保持唯一和一致?一致我的意思是,重新排序的元素在通过它时将产生相同的键
2个回答

React.Children.map考虑到key您为子组件提供的并为它们添加前缀,如果 未向子组件提供 ,则在迭代到映射对象时添加由集合中的索引确定的隐式键

以下是mapChildrenReact src 函数形式的摘录

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 (
    typeof component === 'object' &&
    component !== null &&
    component.key != null
  ) {
    // Explicit key
    return escape(component.key);
  }
  // Implicit key determined by the index in the set
  return index.toString(36);
}

您可以通过使用child.key检查它以了解是否在那里应用了密钥:

const App = () => {
  return (
    <Parent>
      <span key="1">Child 1</span>
      <span>Child 2</span>
      <span>Child 3</span>
    </Parent>
  );
};

const Parent = ({ children }) => {
  return React.Children.map(children, child => (
    <div style={{ background: "lightblue" }}>{'Show me key: ' + child.key}</div>
  ));
};

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script>
<div id="app">

React.children 需要key. 如果您想利用其一致性、重新订购等,请使用密钥。它只是没有显示控制台警告,顺便说一句。

请注意,key如果您看到控制台警告则不是严格要求的。它只是提醒您使用它们。