我在 React 中有下面这段代码,它位于父组件中。基本上它应该做的是对于每一行,它显示一个子组件并创建一个承诺。子组件允许用户更改数据,然后按提交,它使用回调函数使用
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);
}
};
感谢您的帮助。
以上一切都运行良好,我可以在父组件中看到
submitPressedOnEvent
值是 true。然而,当它到达承诺检查状态变量submitPressedOnEvent
是否为真时,它是假的。
奇怪的是,如果我在
SetSubmitPressedOnEvent(true) in the handlesubmit callback function
之后放置一个断点,我可以将鼠标悬停在 Promise 函数中的 if (submitPressedOnEvent)
上,并且可以看到它设置为 true,但是当它实际到达 Promise 中的那行代码时功能又是错误的。
它似乎正在重置为该状态变量的初始值。
您遇到了经典的“陈旧闭包”反应问题,其中间隔回调只能观察其启动时的状态,而不能观察任何后续渲染的状态。您可以通过使用 ref 来解决这个问题,但更好的解决方案是根本不使用轮询布尔状态的间隔。相反,解决来自点击处理程序的承诺!
// 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);
console.log("Showed Event Dialog: " + submitPressedOnEvent);
// 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
// line={currentLineData}
line={eventDialog.row}
// onSubmit = {chosenCategory => {
// currentLineData.category = choseCategory; // ugly mutation - avoid!
// setShowEventDialog(false); // not working
// }}
onSubmit={eventDialog.onSubmit}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/>
}
(我猜你当前的代码)