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

时间:2018-05-12 06:21:59

标签: javascript reactjs

我很清楚reasons为什么在React中创建动态子项时需要添加key道具的原因。对我来说有趣的是以下两段代码的行为

这只使用Array#map

迭代children



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"));
&#13;
<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">
&#13;
&#13;
&#13;

这使用React.Children.map执行相同的操作

&#13;
&#13;
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"));
&#13;
<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">
&#13;
&#13;
&#13;

第一个代码段产生警告

  

数组或迭代器中的每个子项都应该有一个唯一的&#34;键&#34;丙

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

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

2 个答案:

答案 0 :(得分:1)

  

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

以下是mapChildren函数形式React 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);
}

答案 1 :(得分:0)

您可以使用child.key检查是否已在其中应用密钥:

&#13;
&#13;
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"));
&#13;
<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">
&#13;
&#13;
&#13;

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

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