这是编写的代码
function App() {
const [number, setNumber] = useState(1);
const mapper = {
1: 'One',
2: 'two',
3: 'three'
}
const setFirst = () => {
setNumber(1);
console.log(number);
console.log(mapper[number]);
}
const setSecond = () => {
setNumber(2);
console.log(number);
console.log(mapper[number]);
}
const setThird = () => {
setNumber(3);
console.log(number);
console.log(mapper[number]);
}
return (
<div>
<button onClick={() => { setFirst(); }}>One</button>
<button onClick={() => { setSecond() }} >Two</button>
<button onClick={() => { setThird(); }} >Three</button>
</div>
);
}
预期:
单击setFirst()
时,数字应设置为1。
单击setSecond()
时,数字应设置为2。
单击setThird()
时,数字应设置为3。
发生了什么
按顺序单击时
setFirst() -> setSecond() -> setThird()
以重复的方式
输出:
1
One
1
One
2
Two
3
Three
1
One
预期输出:
1
One
2
Two
3
Three
1
One
2
Two
有人可以帮我吗?我需要帮助找出错误的位置。
答案 0 :(得分:1)
正如克里斯在评论中所说,setNumber
是一个异步函数,因此执行后立即看不到它的更新。
此外,您应该知道,在每次渲染时,组件内部的每个方法都“堆叠”在其当前闭包内部。让我详细说明:
button
(假设只是第一个)。渲染button
时,由于setFirst
已链接到它,因此可以想象创建了一种房间,其中复制了setFirst
中使用的所有外部变量。因此,由于setFirst
使用变量number
和mapper
,因此将在此“房间”内创建它们的副本; setFirst
时,您将运行setNumber
。 setNumber
不会不更新number
房间内的setFirst
,但是会更新将在下一个渲染阶段使用的number
; 此示例旨在使您理解为什么单击setSecond
时会记录 1一个:为该渲染初始化setSecond
方法时,{ {1}}仍为number
。
答案 1 :(得分:0)
在事件循环中使用setter函数时。有一个异步功能。您可以设为sync
函数。但是大多数情况下我们不建议这样做,所以我更喜欢使用回调来做到这一点。
setNumber(2, () => {
console.log('');
})
反模式同步方式
Promise.resolve().then(() => {
setNumber(2);
console.log(2);
})