反应异步状态

React async state

我的状态同步有问题。当我点击编辑器的外部(想关闭它)时,我想将实际文本传递回父节点(callback 函数)。 但是当我在 queryText 外面点击时,状态似乎总是落后一步。 (例如:如果编辑器中有 abc,我输入 dCALLBACK: abc,我输入 eCALLBACK: abcd 等等...)。

如果我在我的编辑器之外单击,我怎样才能实现 queryText 的实际状态?

import React, {useEffect, useState} from "react";
import AceEditor from "react-ace";

import "ace-builds/src-noconflict/mode-mysql";
import "ace-builds/src-noconflict/theme-eclipse";
import "./SQLEditor.css"


function SQLEditor({queryTab, active, callback}) {
    const [queryText, setQueryText] = useState(queryTab[active].content)

    //Setting a onClickListener somewhere else
    //This function is getting called when I click outside of the Editor
    function handleClickOutside() {
            document.removeEventListener("mousedown", handleClickOutside);
            console.log("CALLBACK:" + queryText) //Problem here
            callback(active, {content: queryText})
            setInEditor(false)
        }
    }

    //Implementing useEffect for debugging

    useEffect(() => {
        console.log(queryText); //Here I'm getting the right one.
    }
    return (
            <AceEditor
                mode="mysql"
                theme="eclipse"
                name="blah2"
                onChange={(newValue) => {
                    setQueryText(newValue) //Seting text to new value
                    console.log(newValue) //Getting the correct updated value
                }}
                fontSize={16}
            />
        </div>
    )
}
export default SQLEditor;

我以前没有见过 useEffect return 整个组件,我无法在沙箱中将您的代码 运行 。但是,前几天我遇到了同样的问题,让我的状态同步。这是我的处理方式

  1. 创建 useState 挂钩,在点击时 设置
  2. 将状态添加到您的 useEffect 依赖列表
  3. 将点击操作移至您的useEffect方法

它可能看起来像这样

const [someVar, setSomeVar] = useState(null);

const handleClick = (e) => {
    setSomeVar(e.target.value); // or whatever
}

useEffect(() => {
    if (someVar != null) { // useEffect will get called on mount, so this logic is to ensure it will only get called if someVar is not equal to it's default value
        // implement handle click logic here
    }
}, [someVar]) // useEffect will get called each time someVar gets updated because we've added someVar to useEffect's dependencies

在下面添加useEffect,

useEffect(() => {
    if(!inEditor){
        callback(active, {content: queryText});
        console.log(queryText);
    }
}, [inEditor, queryText])

并将您的 handleClickOutside 更新为

function handleClickOutside() {
    document.removeEventListener("mousedown", handleClickOutside);
    setInEditor(false);
}