React useEffect useState 只在迭代中重新渲染一些变量
React useEffect useState only re-rendering some variables in iteration
我在模拟打开一包纸牌的场景。我有一个 UI 显示用户拥有的包数量。如果用户有很多包,我有一个功能可以重复快速打开所有包。如果用户选择 'open all',则用户可以看到包的内容 1100 毫秒,直到呈现下一个打开的包。否则他们将不得不单独打开所有包装,这可能很耗时。
每次打开包后,我将 UI 的状态设置为显示包的内容和用户拥有的包数量。包的内容每次都会呈现,但是计数器不会。计数器在最后更新。我很好奇为什么数据每次迭代都会更新,而计数器却不会。
我切换 openAllMode:
function openAll() {
setOpenAllMode(!openAllMode);
}
那我用效果:
useEffect(() => {
if (openAllMode) {
Promise.all(getDataAsPromises()).then(() =>
setTimeout(() => getUserPackCount(), 1100)
);
}
}, [openAllMode]);
function getDataAsPromises() {
return Array(packCount)
.fill(null)
.map((c, i) =>
new Promise((resolve) => setTimeout(resolve, i * 1100)).then(() =>
getData()
)
);
}
function getData() {
getRandomData(1)
.then((data) => {
setData(data);
setPackCount(packCount - 1);
})
.then(
() => {
console.log("Opened Pack!");
setOpen(true);
},
(error) => {
console.error("Error Opening Pack: " + error);
setOpen(false);
}
);
}
基本上每隔1100ms,'setData'的状态就是重新渲染一次。但是,'setPackCount' 的状态直到结束才重新呈现。
您在 packCount
状态上有一个陈旧的外壳。问题是 packCount
在 getDataAsPromises
回调范围内关闭,每个 setPackCount(packCount - 1);
只是覆盖循环内的先前状态更新。
使用功能状态更新来正确引用任何以前的状态。
setPackCount(packCount => packCount - 1);
我在模拟打开一包纸牌的场景。我有一个 UI 显示用户拥有的包数量。如果用户有很多包,我有一个功能可以重复快速打开所有包。如果用户选择 'open all',则用户可以看到包的内容 1100 毫秒,直到呈现下一个打开的包。否则他们将不得不单独打开所有包装,这可能很耗时。
每次打开包后,我将 UI 的状态设置为显示包的内容和用户拥有的包数量。包的内容每次都会呈现,但是计数器不会。计数器在最后更新。我很好奇为什么数据每次迭代都会更新,而计数器却不会。
我切换 openAllMode:
function openAll() {
setOpenAllMode(!openAllMode);
}
那我用效果:
useEffect(() => {
if (openAllMode) {
Promise.all(getDataAsPromises()).then(() =>
setTimeout(() => getUserPackCount(), 1100)
);
}
}, [openAllMode]);
function getDataAsPromises() {
return Array(packCount)
.fill(null)
.map((c, i) =>
new Promise((resolve) => setTimeout(resolve, i * 1100)).then(() =>
getData()
)
);
}
function getData() {
getRandomData(1)
.then((data) => {
setData(data);
setPackCount(packCount - 1);
})
.then(
() => {
console.log("Opened Pack!");
setOpen(true);
},
(error) => {
console.error("Error Opening Pack: " + error);
setOpen(false);
}
);
}
基本上每隔1100ms,'setData'的状态就是重新渲染一次。但是,'setPackCount' 的状态直到结束才重新呈现。
您在 packCount
状态上有一个陈旧的外壳。问题是 packCount
在 getDataAsPromises
回调范围内关闭,每个 setPackCount(packCount - 1);
只是覆盖循环内的先前状态更新。
使用功能状态更新来正确引用任何以前的状态。
setPackCount(packCount => packCount - 1);