【问题标题】:ReactJS: Is there a way to see the values used for the key property required for listsReactJS:有没有办法查看用于列表所需的键属性的值
【发布时间】:2020-03-31 23:26:04
【问题描述】:

我遇到了一个常见错误:警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”属性。

一般来说,找到有问题的代码很容易,但这次并非如此。我想知道的是正在显示的项目的关键值是什么。

(Q) 有没有办法让我查看渲染的 DOM 中每个键属性的值?

当我检查 HTML 生成的 lists react 已经呈现时,我没有看到 DOM 元素上的 key 属性(我也不希望看到它),但这就是我的我要求看看。 我可以设置一个标志来要求 React 将该键属性值添加到 DOM 以便我可以看到它吗?

这会让我看到我缺少一个键的位置,或者有两个具有相同值的键(这是我认为我遇到的问题)。见Find Duplicated Key in a complicated React component

此时,我正在采用一种有条不紊的方法,一次渲染一个项目以隔离哪个项目有问题,以便我可以归零并找到有问题的代码。

寻找解决方案

在寻找解决方案时,有几篇关于其工作原理以及为什么需要密钥的好文章,如下所示。

【问题讨论】:

  • 你试过使用React DevTool吗?它会让你看到每个组件的道具。
  • 您是否首先设置了密钥?听起来您正在遍历一个数组并为每个值呈现一个反应组件。看看官方文档的Lists and Keys 部分。
  • 最好的解决方案是依靠一个独特的价值。如果您无法根据数据结构的任何特定属性提供它,请使用循环索引。如果由于需要移动列表中的项目而无法使用索引,则可以从数据结构中生成唯一 ID。最好是 JSON.stringify() ;)
  • @Min Lee,我没有使用 React DevTool,我会调查一下。这是否显示关键值?
  • @PatS 是的,开发工具将允许您查看所有组件的树结构以及键、道具和状态。如果您正确设置密钥,您应该能够看到它(例如:<MyComponent key={myUniqueKey}/>

标签: reactjs


【解决方案1】:

这里解释了为什么 Key 很重要,以及如何将它提供给 React 中的一组子项:

下面的示例中有三个 List 组件。如果您在 Chrome DevTools 中打开它并单击“随机排序”,您会发现列表的子项正在发生变化(它们会闪烁),但在第二个示例中,更多的 li 元素正在发生变化,原因是React 正在删除并重新创建li 标签。

高效的示例是第一个和第三个 List 组件,因为 React 知道与其删除这些元素组,不如对它们重新排序,这样更快!

不推荐第三个(JSON.stringify)示例,最好始终依赖数据结构中的唯一属性以避免额外的工作。

const items = Array(10).fill(null).map((_, idx) => ({ id: String(idx) + Math.floor(Math.random() * 9999), title: 'Item '+(idx+1) }));

function List({ children, items, keyProp, indexType }) {
  return (
    <div style={{ borderBottom: '1px solid black', padding: '1em' }}>
      <h2>{children}</h2>
      <ul>
        {items.map((data, idx) => {
          const key = indexType === 'dataStructure'
            ? data[keyProp]
            : indexType === 'jsonStringify'
              ? JSON.stringify(data)
              : idx;
          return (
            <li key={key}>{data.title}, key: {key}</li>
          )
        })}
      </ul>
    </div>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { items };
    this.handleRandomize = this.handleRandomize.bind(this);
  }
  handleRandomize() {
    this.setState({ items: items.slice().sort(() => Math.round(Math.random() * 2) - 1) });
  }
  render() {
    return (
      <div style={{ background: 'red', marginBottom: '2em' }}>
        <button onClick={this.handleRandomize}>Randomize sort</button>
        <List items={this.state.items} indexType='dataStructure' keyProp='id'>
          <p>List renderd with unique "id" from data structure</p>
        </List>
        <List items={this.state.items} indexType='arrayIndex'>
          <p>List rendered with index of the loop</p>
        </List>
        <List items={this.state.items} indexType='jsonStringify'>
          <p>List rendered with JSON.stringify()</p>
        </List>
      </div> 
    )
  }
}

ReactDOM.render(<App />, document.querySelector('#root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多