我有这个简单的 onChange 函数,但我有问题。当我第一次更改输入并例如输入“1”时,我的变量 inputOne
返回空字符串:
const [inputOne, setInputOne] = useState('');
const onChange = (e) => {
setInputOne(e.target.value);
console.log(e.target.value); // first changing of input returns 1
console.log(inputOne); // first changing of input returns EMPTY string
}
<div className="container">
<input type="number" name='input1' value={inputOne} onChange={onChange} />
</div>
但是当我再次更改此输入并再添加一个“1”(总共 11 个)时,我的控制台是:
console.log(e.target.value); // returns 11
console.log(inputOne); // returns 1
为什么我的变量 inputOne
会发生这种情况?
新代码:
const [inputOne, setInputOne] = useState('');
useEffect(() => {
console.log(inputOne);
}, [inputOne])
const onChange = (e) => {
setInputOne(e.target.value);
console.log(e.target.value);
setTimeout(() => {
if(e.target.value){
const filteredpost = posts[0].filter(mfo => mfo.minPrice <= Number(inputOne));
setPostsToShow(filteredpost.slice(0, 20));
setPost(filteredpost);
}else{
const filteredpost = posts[0];
setPostsToShow(filteredpost.slice(0, 20));
setPost(filteredpost);
}}, 1000);
}
答案 0 :(得分:2)
Reactjs 中的状态更新是一个异步过程,因此不会立即反映在下一行,因为它是异步的。
如果你想在状态更新时监控状态,你可以使用 useEffect 钩子,并将你想要跟踪的状态放在它的依赖数组中。
就你而言:
useEffect(() => {
console.log(inputOne);
}, [inputOne])
这个会被触发,每次 inputOne 改变。如果您想使用 inputOne 中的值来调用另一个函数,您应该在 useEffect 内部实现该逻辑,而不是在更新 inputOne 状态的 onChange 函数中执行此操作。
useEffect(() => {
if(inputOne){
const filteredpost = posts[0].filter(mfo => mfo.minPrice <= Number(inputOne));
setPostsToShow(filteredpost.slice(0, 20));
setPost(filteredpost);
}
else
{
const filteredpost = posts[0];
setPostsToShow(filteredpost.slice(0, 20));
setPost(filteredpost);
}
}, [inputOne]);
摆脱超时。没必要。
答案 1 :(得分:1)
setState 是一个异步函数。
在您的情况下, setInputOne 将更改排队并返回一个 Promise, 直到下一个滴答声才会解决这个问题(或者甚至更晚,如果 reacts 认为获得一些性能是值得的)。
所以时间线是这样的:
您可以通过 useEffect 钩子看到这一点:
useEffect(() => {
console.log(`tell me when inputOne changes`);
}, [inputOne])
更新
inputOne 永远不会是您在 onChange 函数中的更新值。 onChange 函数存储最后一个值直到重新渲染。
将您的 setTimeout 传递给 useEffect
OR 将 inputOne 更改为 e.target.value
,因为它们将始终相同。