如何使用 React 在 setState 上更新和显示第一个非空值?
How to update and display first non-empty value on setState with react?
我正在尝试在列表中显示我的输入值。每次我点击提交,我希望它应该按顺序显示输入。
我遇到的问题是,当我尝试提交表单并在列表中显示输入时,它首先显示一个空值。在下一次提交和此后,它会在输入字段中显示以前的值,而不是新值。
还有一条错误消息,但我不明白如何将它与问题联系起来。 It's a warning message regarding controlled/uncontrolled components.
我尝试添加 if
语句来检查每个函数中的空值,但问题 persists.I 我试图通过与所有 input
使用 setState
来控制元素,但没有任何效果。
我查看了 github 上的待办事项列表示例。我想我正试图将它保留在一个功能组件中而不是多个功能组件中,而且我没有使用 class 组件。我尝试按照 Javascript 30 天挑战第 15 天的 wesbos 教程进行操作:本地存储和事件委托。我正在尝试使用 React 而不是普通的 JS。
这是我的组件的样子。
import React, { useEffect, useState } from "react";
import "../styles/LocalStorage.css";
export const LocalStorage = () => {
const [collection, setCollection] = useState([]);
const [value, setValue] = useState();
const [item, setItem] = useState({ plate: "", done: false });
const [display, setDisplay] = useState(false);
//set the value of the input
const handleChange = (e) => {
if (e.target.value === "") return;
setValue(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (value === "" || undefined) return;
setItem((prevState) => {
return { ...prevState, plate: value };
});
addItem(item);
setDisplay(true);
setValue("");
};
const addItem = (input) => {
if (input.plate === "") return;
setCollection([...collection, input]);
};
return (
<div>
<div className="wrapper">
<h2>LOCAL TAPAS</h2>
<ul className="plates">
{display ? (
collection.map((item, i) => {
return (
<li key={i}>
<input
type="checkbox"
data-index={i}
id={`item${i}`}
checked={item.done}
onChange={() =>
item.done
? setItem((state) => ({ ...state, done: false }))
: setItem((state) => ({ ...state, done: true }))
}
/>
<label htmlFor={`item${i}`}>{item.plate}</label>
</li>
);
})
) : (
<li>Loading Tapas...</li>
)}
</ul>
<form className="add-items" onSubmit={handleSubmit}>
<input
type="text"
name="item"
placeholder="Item Name"
required
value={value}
onChange={handleChange}
/>
<button type="submit">+ Add Item</button>
</form>
</div>
</div>
);
};
由于 setState
函数是异步的,您不能在触发 setItem(...)
后立即使用状态值 item
。为确保您获得 addItem
函数的最新值:
setItem((prevState) => {
const newItem = { ...prevState, plate: value };
addItem(newItem); // Now, it's getting the updated value!
return newItem;
});
关于受控和非受控组件,您可以阅读相关文档here。要解决您的问题,您可以使用空字符串初始化值状态:
const [value, setValue] = useState('');
我正在尝试在列表中显示我的输入值。每次我点击提交,我希望它应该按顺序显示输入。
我遇到的问题是,当我尝试提交表单并在列表中显示输入时,它首先显示一个空值。在下一次提交和此后,它会在输入字段中显示以前的值,而不是新值。
还有一条错误消息,但我不明白如何将它与问题联系起来。 It's a warning message regarding controlled/uncontrolled components.
我尝试添加 if
语句来检查每个函数中的空值,但问题 persists.I 我试图通过与所有 input
使用 setState
来控制元素,但没有任何效果。
我查看了 github 上的待办事项列表示例。我想我正试图将它保留在一个功能组件中而不是多个功能组件中,而且我没有使用 class 组件。我尝试按照 Javascript 30 天挑战第 15 天的 wesbos 教程进行操作:本地存储和事件委托。我正在尝试使用 React 而不是普通的 JS。
这是我的组件的样子。
import React, { useEffect, useState } from "react";
import "../styles/LocalStorage.css";
export const LocalStorage = () => {
const [collection, setCollection] = useState([]);
const [value, setValue] = useState();
const [item, setItem] = useState({ plate: "", done: false });
const [display, setDisplay] = useState(false);
//set the value of the input
const handleChange = (e) => {
if (e.target.value === "") return;
setValue(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (value === "" || undefined) return;
setItem((prevState) => {
return { ...prevState, plate: value };
});
addItem(item);
setDisplay(true);
setValue("");
};
const addItem = (input) => {
if (input.plate === "") return;
setCollection([...collection, input]);
};
return (
<div>
<div className="wrapper">
<h2>LOCAL TAPAS</h2>
<ul className="plates">
{display ? (
collection.map((item, i) => {
return (
<li key={i}>
<input
type="checkbox"
data-index={i}
id={`item${i}`}
checked={item.done}
onChange={() =>
item.done
? setItem((state) => ({ ...state, done: false }))
: setItem((state) => ({ ...state, done: true }))
}
/>
<label htmlFor={`item${i}`}>{item.plate}</label>
</li>
);
})
) : (
<li>Loading Tapas...</li>
)}
</ul>
<form className="add-items" onSubmit={handleSubmit}>
<input
type="text"
name="item"
placeholder="Item Name"
required
value={value}
onChange={handleChange}
/>
<button type="submit">+ Add Item</button>
</form>
</div>
</div>
);
};
由于 setState
函数是异步的,您不能在触发 setItem(...)
后立即使用状态值 item
。为确保您获得 addItem
函数的最新值:
setItem((prevState) => {
const newItem = { ...prevState, plate: value };
addItem(newItem); // Now, it's getting the updated value!
return newItem;
});
关于受控和非受控组件,您可以阅读相关文档here。要解决您的问题,您可以使用空字符串初始化值状态:
const [value, setValue] = useState('');