无法在React中获取密钥数组元素的ID

时间:2018-03-09 08:54:35

标签: javascript reactjs

根据React文档中的说明,可以通过它keys设置array元素的ID。 实际上问题是,反应在哪里根据指令获取ID数据(并且它不是元素的索引):

来自React doc:选择密钥的最佳方法是使用一个字符串,该字符串在其兄弟姐妹中唯一标识列表项。大多数情况下,您会使用数据中的ID作为键:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

但由于某种原因,它对我不起作用:

import React from 'react';
import ReactDOM from 'react-dom';

class MyComponent extends React.Component {
  render() {
    const map = this.props.list.map(
      (li) => <li key={li.id}>{li}</li> // keys does an attached
    );
    return (
      <div>
        <ul>
          {map} 
        </ul>
      </div>
    )
  }
}

const testRenderer = ['1', '2', '3', '4', '5'];

ReactDOM.render(
  <MyComponent list={testRenderer} />,
  document.getElementById('root'));

3 个答案:

答案 0 :(得分:0)

这里的问题是你在testRenderer传递一个数字数组,但你的map函数在数组的每个项目中都需要id。试试这个

import React from 'react';
import ReactDOM from 'react-dom';
class MyComponent extends React.Component {
  render() {
    const map = this.props.list.map(
      (li, index) => <li key={index.toString()}>{li}</li>
    );
    return (
      <div>
        <ul>
          {map} 
        </ul>
      </div>
    )
  }
}

const testRenderer = ['1', '2', '3', '4', '5'];

ReactDOM.render(
  <MyComponent list={testRenderer} />,
  document.getElementById('root'));

现在,您使用testRenderer项作为key值。

答案 1 :(得分:0)

问题是您使用map()函数迭代数组,然后尝试在循环内调用对象。

li.id不存在,因为li不是对象。它是您迭代的数组中的值。

您可以像这样使用数组键值:

const map = this.props.list.map(
  (li, key) => <li key={key}>{li}</li> // where key will be 0, 1, 2, 3, 4
);

答案 2 :(得分:-1)

index中使用元素array不是创建ID's的正确方法。与此相关,我们还直接通过 React

发表声明

作为最后的手段,您可以将数组中的项目索引作为键传递。如果项目从不重新排序,这可以很好地工作,但重新排序会很慢。

当索引用作键时,重新排序也会导致组件状态出现问题。组件实例根据其密钥进行更新和重用。如果键是索引,则移动项目会更改它。因此,受控输入之类的组件状态可能会以意想不到的方式混淆和更新。

您可以从高级官方指南中查看更多信息:https://reactjs.org/docs/reconciliation.html#recursing-on-children

并找到两个例子,说明为什么在键部分中不使用键的索引非常重要。

因此,如果我们想要做得好,我们需要为传入的state创建一个array更新方法,为每个ID创建一个唯一的element传入的外部array。通过这种方式,我们将对任意长度的传入array进行完全控制,并且如果对ID's的元素进行重新排序,我们也永远不会通过array进行错误的排序。< / p>

import React from 'react';
import ReactDOM from 'react-dom';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      arrayObj: {
          id: '',
          list: ''
      }
    }
  }

  componentWillMount() { // make new state with 
                         // object besides on incoming array
    let count = 0;
    let arrCount = [];
    let arrs = this.props.list;

    this.props.list.forEach( // make the ID for each element of an array
      (li) => {
        arrCount.push(++count); 
      } 
    );

    this.setState({
      arrayObj: {
          id: arrCount,
          list: arrs
        }
    })
  }

  render() {
    return (
      <ul>
        <MakeList obj={this.state.arrayObj} />
      </ul>
    )
  }
}

class MakeList extends React.Component{ // support component for 
                                    // render current obj state children
  render() {
    let object = this.props.obj;
    let arr = [];

    for (var key in object.list) {
      arr.push(<li key={object.id[key]}>{object.list[key]}</li>)
    }
    return arr;
  }
}

const testRenderer = ['11', '22', '33', '44', '55'];

ReactDOM.render(
  <MyComponent list={testRenderer} />,
  document.getElementById('root'));