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

Maa*_*eeb 10 javascript reactjs

我很清楚在 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"));
Run Code Online (Sandbox Code Playgroud)
<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">
Run Code Online (Sandbox Code Playgroud)

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

const App = () => {
  return (
    <Parent>
      <span>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" }}>{child}</div>
  ));
};

ReactDOM.render(<App />, document.getElementById("app"));
Run Code Online (Sandbox Code Playgroud)
<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">
Run Code Online (Sandbox Code Playgroud)

第一个片段产生警告

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

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

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

Shu*_*tri 6

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);
}
Run Code Online (Sandbox Code Playgroud)