我正在努力在 React 中使用 useState 处理列表。我必须连续两次将一个项目添加到列表中,并且只添加第二个项目。代码:
App.js
import React, { useState } from "react";
import ItemForm from "./itemForm";
function App() {
const [itemList, setItemList] = useState([]);
function addItem(item) {
setItemList([...itemList, item]);
}
return (
<div>
<ItemForm onAddItem={ addItem } />
{ itemList &&
itemList.map((item, i) => <ul key={ i + itemList } >{ item }</ul>) }
</div>
);
}
export default App;
ItemForm.js
import React, { useState } from 'react';
function ItemForm({ onAddItem }) {
const [inputValue, setInputValue] = useState('');
function handleSubmit(e) {
e.preventDefault();
var item = e.target.item.value;
// Here, I have to call onAddItem twice.
onAddItem(item);
onAddItem(item + " second time");
}
return (
<div>
<form onSubmit={ handleSubmit } >
<input value={ inputValue }
onChange={(e) => setInputValue(e.target.value) } name="item"></input>
<button type="submit">Add</button>
</form>
</div>
)
}
export default ItemForm;
这是应用的实际行为:
这是预期的行为:
为什么会发生这种情况以及如何解决它?
最佳答案
状态更新是异步的
对于您的两次调用,itemsList 数组完全相同。 :
假设您有一个数组:[1,2,3]
。您的代码本质上所做的就是第一次将其设置为 [1,2,3,4]
,第二次将其设置为 [1,2,3,5]
.
setItemList([...itemList, item]) //[1,2,3,4]
setItemList([...itemList, item]) //[1,2,3,5]
第二次更新中的数组仍使用原始值。
实现此目的的一种方法是使用此模式,该模式使用先前的状态。这是使用先前状态的可靠方法。
import React, { useState } from "react";
import ItemForm from "./itemForm";
function App() {
const [itemList, setItemList] = useState([]);
function addItem(item) {
setItemList(itemList => ([...itemList, item]));
}
return (
<div>
<ItemForm onAddItem={ addItem } />
{ itemList &&
itemList.map((item, i) => <ul key={ i + itemList } >{ item }</ul>) }
</div>
);
}
export default App;
import React, { useState } from 'react';
function ItemForm({ onAddItem }) {
const [inputValue, setInputValue] = useState('');
function handleSubmit(e) {
e.preventDefault();
var item = e.target.item.value;
// Here, I have to call onAddItem twice.
onAddItem(item);
onAddItem(item + " second time");
}
return (
<div>
<form onSubmit={ handleSubmit } >
<input value={ inputValue }
onChange={(e) => setInputValue(e.target.value) } name="item"></input>
<button type="submit">Add</button>
</form>
</div>
)
}
export default ItemForm;
关于javascript - 使用 useState 多次更新列表会导致错误的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69342421/