在 promise 中无法识别状态变量的问题

Issue with State Variables not being recognised within a promise

提问人:Jeffrey Menashe 提问时间:11/3/2023 最后编辑:Jeffrey Menashe 更新时间:11/4/2023 访问量:33

问:

我在 React 中有这段代码,它位于父组件中。基本上,它应该做的是针对每一行,它显示一个子组件并创建一个 promise。子组件允许用户更改数据,然后按 submit,该组件使用回调函数来更新父组件中的状态变量,使用submitPressedOnEventSetSubmitPressedOnEvent(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。submitPressedOnEventsubmitPressedOnEvent

奇怪的是,如果我在 之后放置一个断点,我可以将鼠标悬停在 promise 函数中并可以看到它被设置为 true,但是当它实际到达 promise 函数中的那行代码时,它又是 false。SetSubmitPressedOnEvent(true) in the handlesubmit callback functionif (submitPressedOnEvent)

它似乎正在重置为该状态变量的初始值。

ReactJS 异步 承诺

评论

0赞 Bergi 11/3/2023
请在代码中包含 的定义。我敢打赌它实际上不是一个变量,而是一个蚂蚁,你正在使用一个反应函数组件进行状态处理?submitPressedOnEventconst
0赞 Jeffrey Menashe 11/4/2023
你好。非常感谢您的回复,非常感谢。你是100%正确的。该设置是一个常量,而不是一个变量。这是非常具有误导性的,我对此表示歉意。此外,是的,我正在使用 react 函数组件进行状态处理。

答:

0赞 Bergi 11/4/2023 #1

你有经典的“陈旧闭包”反应问题,其中间隔回调只能观察启动时的状态,而不能观察任何以后渲染的状态。你可以通过使用 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(…)