javascript - 多次使用 useState 更新列表会导致错误输出
问题描述
我正在努力处理 React 中的 useState 列表。我必须连续两次将一个项目添加到列表中,并且只添加第二个项目。编码:
应用程序.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;
推荐阅读
- android - 如何在 Autocomplete Places _ Places API 中获取城市和州名
- ios - Graphql 参数返回 optional(optional("value")) - iOS
- css - 通过外包装 div 垂直滚动左右 div,将右 div 滚动到水平滚动 - 始终可见
- node.js - 为什么我在 Kubernetes 上使用 Axios 时出现 ENOTFOUND 错误
- android - 与元素类型“item”关联的属性“name”的值不能包含“<”字符
- selenium - 无法在文件上传窗口中输入文件路径
- elasticsearch - 如何将弹性搜索索引从 5.6.2 版本迁移到 6.8?
- javascript - VueJS 变异 od 重复 v-model (:value, @input)
- azure - (ADAL) 与 Ionic 3 的集成得到“我们无法发行代币”
- python - 将一个3x10的张量合并到1x10,用什么方法?