简体   繁体   English

State 不会异步更新 function

[英]State does not update in async function

Could you please help me understand why my state was not updated when I called two async functions in the first useEffect?你能帮我理解为什么当我在第一个 useEffect 中调用两个异步函数时我的 state 没有更新吗? and what is the best way to handle async data in the case that I don't know which one comes first (API1 or API2)?在我不知道哪个先出现(API1 或 API2)的情况下,处理异步数据的最佳方法是什么?

Thank you!谢谢!

const MyClass = () => {
    const [myState, setMyState] = useState([]);

    useEffect(() => {
        callApi1();
        callApi2();
    }, []);

    const callApi1 = () => {
        fetch(...).then(result => {
            // the result of API 1 always comes first and result is not empty
            setMyState(result);
        )};
    }

    const callApi2 = () => {
        fetch(...).then(result => {
            // the result of API 2 always comes 5 - 10 seconds after the API 1
            console.log(myState) => [], WHY?
        });
    }
}

(1.) "... why my state was not updated..." (1.) “……为什么我的 state 没有更新……”

Your state was updated, but the callback function captures the old state of myState (as a closure ).您的 state更新,但回调 function 捕获了 myState 的旧myState (作为闭包)。 That means myState inside the callback function will always stay the same as it was when the function was created.这意味着回调myState中的 myState 将始终与创建 function 时相同。 (And it is created only when callApi2() is invoked.) (并且它仅在调用 callApi2() 时创建。)

You can not access the current up-to-date state inside an asynchronous callback.您无法在异步回调中访问当前最新的 state。

(2.) "...best way to handle async data in the case that I don't know which one comes first" (2.) “......在我不知道哪个先出现的情况下处理异步数据的最佳方式”

It depends on your use case.这取决于您的用例。
Generally, you would set some states from your callbacks (eg your setMyState(result) ), and a different part of your program will do something else dependent on these states, eg useEffect(()=>{ /* do something */ }, [ myState ]) .一般来说,你会从你的回调中设置一些状态(例如你的setMyState(result) ),你程序的不同部分会根据这些状态做一些其他的事情,例如useEffect(()=>{ /* do something */ }, [ myState ])

eg:例如:

const MyClass = () => {
    const [myState, setMyState] = useState([]);
    const [myState2, setMyState2] = useState([]);
    const [allDone, setAllDone] = useState(false);

    useEffect(() => {
        callApi1();
        callApi2();
    }, []);

    useEffect(() => {
        console.log( 'myState/myState2:', myState, myState2);
        if( myState.length && myState2.length ){
            setAllDone(true);
        }
    }, [ myState, myState2 ]);

    const callApi1 = () => {
        fetch(...).then(result => {
            setMyState(result);
        )};
    }

    const callApi2 = () => {
        fetch(...).then(result => {
            setMyState2(result);
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM