状态变量在承诺中未被识别的问题

问题描述 投票:0回答:1

我在 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 中的那行代码时功能又是错误的。

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

reactjs asynchronous promise
1个回答
0
投票

您遇到了经典的“陈旧闭包”反应问题,其中间隔回调只能观察其启动时的状态,而不能观察任何后续渲染的状态。您可以通过使用 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} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /> }

(我猜你当前的代码)

© www.soinside.com 2019 - 2024. All rights reserved.