如何在列表项之前添加正确的反应

时间:2019-05-25 17:12:38

标签: javascript reactjs

我无法正确地预先添加动态生成的列表项

显示我的意思是设置jsfiddle

  1. 添加新项(输入1)
  2. 添加新值(输入a)
  3. 添加新项(输入2)

您将看到该值停留在顶部,现在位于项目2内。

我如何解决此问题,以使添加的第二个项目具有空值,而第一个项目保持其值?

  class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
        items: []
    }
  }

  addItem = (e) => {
    this.setState({
        items: [e.target.value, ...this.state.items]
    })
  }



  render() {
    return (
        <div>
        <p>Add new Item</p>
        <input type="text" onChange={this.addItem}></input>
        <ul>
        {this.state.items.map(item => (
          <li key={item.id}>
            <h4>{item}</h4>
            <p>add New Value</p>
            <input type="text"></input>
          </li>
        ))}
        </ul>
      </div>

    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))

1 个答案:

答案 0 :(得分:0)

问题在这里:

        {this.state.items.map(item => (
          <li key={item.id}>
            ...

React使用key道具来引用列表中的每个项目,因此它对于每个项目都应该是唯一的(且稳定)。您的item没有id属性,它只是输入中的字符串值,因此item.id是未定义的。只要您不希望任何重复的项目名称,就可以使用item本身(输入值)作为键。

要使其更强大,可以将项目存储为具有valueid属性的对象,并在创建每个项目时为其生成唯一的ID。这是一种简单的方法:

class TodoApp extends Component {

  state = {
    items: []
  }

  lastID = 0;

  addItem = (e) => {
    this.setState({
      items: [{ value: e.target.value, id: this.lastID++}, ...this.state.items]
    })
  }

  render() {
    ...
    {this.state.items.map(item => (
      <li key={item.id}>
      <h4>{item.value}</h4>
        ...
  }
}

请注意,我们正在对lastID进行突变,但是在这种情况下,这是可以的,因为它是类属性,并且不存储在state中(更改时不会引起重新渲染)。