反应 - 如何将项目添加到列表多次一帧
react - how to add item to list multi-times one frame
看了useState
set list
...等相关文章后,解决了我的部分问题。
但是我遇到的一个问题场景并没有解决,那就是...
- 一个组件提供了添加项目的功能。 (例如
addItemData(data)
)
- 另一个组件通过for循环多次调用添加项函数。 (例如
dataList.foreach(data => addItemData(data.productItem))
)
我的添加函数做了什么:
...
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));
看了useState
set list
...等相关文章后,解决了我的部分问题。
但是我遇到的一个问题场景并没有解决,那就是...
- 一个组件提供了添加项目的功能。 (例如
addItemData(data)
) - 另一个组件通过for循环多次调用添加项函数。 (例如
dataList.foreach(data => addItemData(data.productItem))
)
我的添加函数做了什么:
...
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));