提问人:Jeffrey Menashe 提问时间:11/3/2023 最后编辑:Jeffrey Menashe 更新时间:11/4/2023 访问量:33
在 promise 中无法识别状态变量的问题
Issue with State Variables not being recognised within a promise
问:
我在 React 中有这段代码,它位于父组件中。基本上,它应该做的是针对每一行,它显示一个子组件并创建一个 promise。子组件允许用户更改数据,然后按 submit,该组件使用回调函数来更新父组件中的状态变量,使用submitPressedOnEvent
SetSubmitPressedOnEvent(true).
const processRowsAsync = async (rows: any[]) => {
// Iterate over the array of rows
for (const row of rows) {
console.log("Processing Next Row: " + submitPressedOnEvent);
// Set the current line data
setCurrentLineData({ ...row, category: "" });
console.log("Set Curent Line Data: " + submitPressedOnEvent);
setShowEventDialog(true);
console.log("Showed Event Dialog: " + submitPressedOnEvent);
// Wait for the user to click the Submit button
await new Promise((resolve) => {
console.log("Creating Promise: " + submitPressedOnEvent);
const interval = setInterval(() => {
console.log("Interval : " + submitPressedOnEvent);
if (submitPressedOnEvent) {
console.log("Fulfilled Promise: " + submitPressedOnEvent);
setSubmitPressedOnEvent(false);
console.log("Set Pressed Event to False: " + submitPressedOnEvent);
clearInterval(interval);
resolve(null);
console.log("Resolved Promise: " + submitPressedOnEvent);
}
}, 500);
});
// Output the selected category to the console
console.log("Selected Category: " + currentLineData?.category + " : " + submitPressedOnEvent);
}
};
感谢您的任何帮助。
以上所有工作都很好,我可以在父组件中看到该值为 true。但是,当它到达 promise 以检查状态变量是否为 true 时,它是 false。submitPressedOnEvent
submitPressedOnEvent
奇怪的是,如果我在 之后放置一个断点,我可以将鼠标悬停在 promise 函数中并可以看到它被设置为 true,但是当它实际到达 promise 函数中的那行代码时,它又是 false。SetSubmitPressedOnEvent(true) in the handlesubmit callback function
if (submitPressedOnEvent)
它似乎正在重置为该状态变量的初始值。
答:
你有经典的“陈旧闭包”反应问题,其中间隔回调只能观察启动时的状态,而不能观察任何以后渲染的状态。你可以通过使用 ref 来解决这个问题,但更好的解决方案是根本不使用轮询布尔状态的区间。相反,请解决点击处理程序的 promise!
// remove those:
// const [currentLineData, setCurrentLineData] = useState();
// const [showEventDialog, setShowEventDialog] = useState(false);
// instead use:
const [eventDialog, setEventDialog] = useState(null);
const processRowsAsync = async (rows: any[]) => {
for (const row of rows) {
// setCurrentLineData({ ...row, category: "" });
// setShowEventDialog(true);
// Wait for the user to click the Submit button
const category = await new Promise((resolve) => {
// open the dialog and pass the submit handler:
setEventDialog({ row, onSubmit: resolve });
// ^^^^^^^^^^^^^^^^^
});
// Output the selected category to the console
console.log("Selected Category: " + category);
}
};
// if (showEventDialog) {
if (eventDialog != null) {
return <EventDialog
// row={currentLineData}
row={eventDialog.row}
onSubmit={chosenCategory => {
// currentLineData.category = choseCategory; // ugly mutation - avoid!
// setShowEventDialog(false); // not working
eventDialog.onSubmit(chosenCategory);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
setEventDialog(null); // close it
}}
/>
}
(我在这里猜测你当前的代码)
您还可以简化 to 和 after the 处理任务。<EventDialog {...eventDialog} />
setEventDialog(null);
await new Promise(…)
评论
submitPressedOnEvent
const