【问题标题】:counting on setState in a loop, rendering li with key在循环中依靠 setState,用 key 渲染 li
【发布时间】:2019-12-17 13:33:36
【问题描述】:

我有一个带有 items 数组的应用程序类,它应该有具有唯一 id 的项目,当单击按钮时会更新:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      saveId: 1,
      items: []
    };
  }

  addItem(name) {
    let item = {
      id: this.state.saveId,
      name: name
    }
    this.setState({saveId: this.state.saveId + 1});
    let items = this.state.items;
    items.push(item);
    this.setState({items: items});
  }

  updateCount() {
    this.addItem("one");
    this.addItem("two");
    this.addItem("three");
  }

  render() {
    return (
          <div>
                <button
                  onClick={() => this.updateCount()}
                >
                  SaveId: {this.state.saveId}
                </button>
                <ul>
                  {this.state.items.map((item, i) => {
                    return <li key={item.id}>{item.name + "" + item.id}</li>
                  })}
                </ul>
        </div>);
  }
}

export default App;

当按钮被点击时,addItem 会被调用 3 次,更新最后保存的 id 的状态。 updateCount 函数完成后:

this.state.saveId = 2
this.state.items = [
  {
     name: "one",
     id: 1
  },
  {
     name: "two",
     id: 1
  },
  {
     name: "three",
     id: 1
  }
]

这会生成“警告:遇到两个使用相同密钥的孩子,1。”。

我知道 setState 是异步的,它们在循环调用时是批量调用的。

我的问题是: 有没有办法绕过它而不直接用this.state.saveId++改变状态?

谢谢。

【问题讨论】:

    标签: javascript reactjs asynchronous setstate


    【解决方案1】:

    使用setState的函数版本。它将以先前的状态传递给您,您可以使用它来制作新的状态。如果多个设置状态快速连续发生,您可以确定您只会获得最近的状态,而不是设置状态开始发生之前的状态。此外,当您推送到项目时,您当前正在改变旧状态。相反,创建一个新数组并添加到其中。

    addItem(name) {
      this.setState(prevState => {
        let item = {
          id: prevState.saveId,
          name: name,
        }
        // shallow copy of the array, with an extra item at the end
        const newItems = [...prevState.items, item];
        return {
          items: newItems,
          saveId: prevState.saveId + 1,
        }
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      相关资源
      最近更新 更多