Javascript 异步函数中的状态不更新

Javascript 异步函数中的状态不更新,javascript,reactjs,react-hooks,use-effect,use-state,Javascript,Reactjs,React Hooks,Use Effect,Use State,您能帮助我理解为什么在第一次useEffect中调用两个异步函数时我的状态没有更新吗?在我不知道哪一种先到的情况下(API1或API2),处理异步数据的最佳方法是什么 谢谢大家! const MyClass = () => { const [myState, setMyState] = useState([]); useEffect(() => { callApi1(); callApi2(); }, []); co

您能帮助我理解为什么在第一次useEffect中调用两个异步函数时我的状态没有更新吗?在我不知道哪一种先到的情况下(API1或API2),处理异步数据的最佳方法是什么

谢谢大家!

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.“…为什么我的状态没有更新…”

您的状态已更新,但回调函数将捕获旧状态
myState
(作为一个函数)。这意味着回调函数中的
myState
将始终保持与创建函数时相同的状态。(并且它仅在调用callApi2()时创建。)

无法在异步回调中访问当前最新状态

(2.“…在我不知道哪一个先到的情况下处理异步数据的最佳方法”

这取决于您的用例。
通常,您会从回调中设置一些状态(例如,
setMyState(result)
),并且程序的不同部分会根据这些状态执行其他操作,例如,
useffect(()=>{/*dosomething*/},[myState])

e、 g:

(1.“…为什么我的状态没有更新…”

您的状态已更新,但回调函数将捕获旧状态
myState
(作为一个函数)。这意味着回调函数中的
myState
将始终保持与创建函数时相同的状态。(并且它仅在调用callApi2()时创建。)

无法在异步回调中访问当前最新状态

(2.“…在我不知道哪一个先到的情况下处理异步数据的最佳方法”

这取决于您的用例。
通常,您会从回调中设置一些状态(例如,
setMyState(result)
),并且程序的不同部分会根据这些状态执行其他操作,例如,
useffect(()=>{/*dosomething*/},[myState])

e、 g:


回答你问题的第一部分。你可以等待第一个回复,然后请求第二个回复?@NooruddinLakhani我认为这不好,因为第二个请求需要很多时间,我们不能等待。关于回复,如果你想同时等待两个,您可以添加一个方法,该方法在收到每个结果时将被调用,并且只在第二次调用时执行某些操作。回答问题的第一部分。您可以等待第一次响应,然后请求第二次响应?@NooruddinLakhani我认为这不好,因为第二次请求需要很多时间,我们不能等待。关于响应,如果您想同时等待这两个响应,您可以添加一个方法,该方法将在收到每个结果时被调用,并且只在第二次调用时执行某些操作
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);
        });
    }
}