反应 - 如何将项目添加到列表多次一帧

react - how to add item to list multi-times one frame

看了useState set list...等相关文章后,解决了我的部分问题。
但是我遇到的一个问题场景并没有解决,那就是...

我的添加函数做了什么:

...
const [list, setList] = useState([])
...
addItemData(data) {
    setList([..., data]);
}

结果是只添加了最新的项目,而不是全部。 我认为是他们在同一帧中调用 addItemData 以便 list 是同一个。

我该怎么做才能解决这个问题?

更新状态是异步的,这意味着调用 setList() 不会立即更新您的状态。查看以下尝试调用 setCount() 两次的示例:

const {useState} = React;

const App = () => {
  const [count, setCount] = useState(0);
  
  const addTwo = () => {
    setCount(count+1); // does not update count straightaway
    setCount(count+1); // when this runs, count is still 0,  it it performs setCount(0+1)
  }
  
  return <div>
    <p>{count}</p>
    <button onClick={addTwo}>Click me</button>
  </div>;
}

ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

上述方法不起作用有两个原因。一个是 setCount() 是异步的,因此 count 不会在下一个 setCount() 紧随其后立即运行时更新。请记住,这可以写成迭代两次的 for 循环(如您的示例)。 count 不更新的另一个原因是 count 通过值(而不是通过引用)传递给 setCount(),所以 setCount() 不可能更新你的 count 变量(理论上,在您传递数组时,您的情况是可能的,但 React 不会修改现有引用)。

如果你想访问最新版本的状态,那么你可以传递一个回调函数,这将为你提供最新的状态值:

setList(currList => [...currList, data]);

你可以从上面的例子中看到这个工作:

const {useState} = React;

const App = () => {
  const [count, setCount] = useState(0);
  
  const addTwo = () => {
    setCount(currCount => currCount+1);
    setCount(currCount => currCount+1); // grab current count value updated by previous `setCount()` and return the new value we want to set the state to
  }
  
  return <div>
    <p>{count}</p>
    <button onClick={addTwo}>Click me</button>
  </div>;
}

ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

理想情况下,您应该避免多次调用 setList() 来累积您的状态,而是先使用诸如 .map() 之类的东西来累积您的值数组,然后使用您的映射数组:

addItemData(data) { // data is an array
  setList([...list, ...data]);
}
...
addItemData(dataList.map(({productItem}) => productItem));