我正在做一个反应项目,并且对使用当前正确的状态值有疑问。我已经在一个小的虚拟项目中重新创建了该问题,该项目包含一个父组件和一个子组件。 Child从Parent组件传递到props,一个状态变量和一个使用反应挂钩(useState)更新所述状态的函数。在驻留在Parent组件中的原始函数中,是对第二个函数的调用,该第二个函数根据当前状态执行操作。我的控制台日志和结果表明,传递的函数会发送回正确的值以进行更新,但是以下函数未使用更新后的值,而是似乎始终落后于一个渲染器。
我尝试使用async / await以及useEffect挂钩。我已经可以在这个小的虚拟项目中使用useEffect的一些变体来获得“预期”结果,但是它并没有转化为实际的项目,因为它们有更多的函数调用(也取决于状态值),尽管我可能只是误会/做错了什么。
export const Parent = () => {
const [count, setCount] = useState(0);
const [fruit, setFruit] = useState(null);
const counter = (index) => {
console.log("index passed in: ", index);
setCount(index);
secondMethod()
}
const secondMethod = () => {
console.log('state of count in second method', count);
const arr = ['apple', 'cherry', 'orange', 'kiwi', 'berry'];
setFruit(arr[count]);
}
return (
<div>
<p>Hello from Parent, current count: {count}</p>
<Child counter={counter} count={count}/>
<p>result of second method: {fruit}</p>
</div>
);
}
export const Child = ({ counter, count }) => {
return (
<div>
<p>Child comp</p>
<button onClick={() => counter(count + 1)}>
Click on send counter
</button>
</div>
);
}
索引上的控制台日志值以及{count}输出正确。来自secondMethod的控制台日志的结果,因此setFruit的状态不正确,并且使用了后面一个渲染的状态?因此count将显示为1,但是secondMethod仍将count设置为0,因此显示“ apple”而不是“ cherry”。感谢所有帮助/建议,谢谢!
答案 0 :(得分:0)
反应状态更新操作是异步的,并且为提高性能而进行了批处理。不能保证console.log('state of count in second method', count);
会反映出更新后的状态。
解决方案1:使用传入的index
中的secondMethod
值作为参数
解决方案2:使用fruit
钩子更新{strong} count
之后,更新useEffect
。将secondMethod
替换为:
useEffect(() => {
console.log('state of count in useEffect', count);
const arr = ['apple', 'cherry', 'orange', 'kiwi', 'berry'];
setFruit(arr[count]);
}, [count, setFruit]);
解决方案3::如果您的州之间严重依赖,那么也许它们应该属于同一个州。这样,您可以使用setState的函数版本,该函数版本始终会收到正确的先前值。
// join separate states together
const [fruitCount, setFruitCount] = useState({ count: 0, fruit: null });
const counter = index => {
setFruitCount({ count: index });
secondMethod();
};
const secondMethod = () => {
const arr = ["apple", "cherry", "orange", "kiwi", "berry"];
// use setState function, count is taken from the previous state value
setFruitCount(prevState => ({ ...prevState, fruit: arr[prevState.count] }));
};