我正在处理一个反应项目,在使用当前正确的状态值时遇到问题。 我已经在一个包含父组件和子组件的小型虚拟项目中重新创建了该问题。子组件是从父组件、一个状态变量和一个利用反应钩子(useState(更新所述状态的函数传递的道具。 在驻留在父组件中的原始函数中,是对第二个函数的调用,该函数根据当前状态执行操作。 我有控制台日志和结果显示传递的函数发送回正确的值进行更新,但以下函数不使用更新的值,而是似乎总是落后一个渲染。
我尝试使用 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 的状态不正确,并使用后面一个渲染的状态? 所以计数将显示为 1,但第二个方法仍将计数为值 0,因此显示"苹果"而不是"樱桃"。 我感谢任何和所有的帮助/建议,谢谢!
React 状态更新操作是异步的,并且会进行批处理以提高性能。无法保证console.log('state of count in second method', count);
将反映更新的状态。
解决方案 1:使用传入secondMethod
中的index
值作为参数传入
解决方案 2:更新count
后,使用useEffect
挂钩更新fruit
。将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] }));
};