在回调内部调用时,反应 useState 不能正确更新

react useState don't update properly when it's called inside callback

我要计算加载的 api。我用的是函数组件。

function Screen(props) {
    const [count, setCount] = useState(0)
    useEffect(() => {
        loadData();
        () => { return null; }
    }, [])
    const loadData = () => {
        axios({ url: API_BASE_URL + 'countries', method: 'get' }).then((res)=>{
            setCount(count+1)
        })
        axios({ url: API_BASE_URL + 'regions', method: 'get' }).then((res)=>{
            setCount(count+1)
        })
    }
    useEffect(() => {
        console.info(count)  // this shows 0, 1, it never be 2
    }, [count])
    return <div></div>
}

我的代码有什么问题?我认为它最后应该打印 2 谢谢

count 被传递给 then 的闭包 捕获为 作为 0。实际上,您正在调用 setCount(0 + 1)。可以在此处找到非常详尽的解释:https://overreacted.io/a-complete-guide-to-useeffect/

这是您的代码的更新版本,它修复了问题:

import React, { useCallback, useEffect, useState } from 'react';

const fakeApi = (delay = 400, val = null): Promise<typeof val> => new Promise(resolve => {
  setTimeout(resolve, delay, val);
});

const Count: React.FC = () => {
  const [count, setCount] = useState(0);

  const loadData = useCallback(() => {
    fakeApi(1000).then(() => {
      setCount(count => count + 1); // use the function form of setState to get the current state value without being *dependent* on it.
    });

    fakeApi(2000).then(() => {
      setCount(count => count + 1); // same as above.
    });
  }, []); // no dependencies => loadData is constant

  useEffect(() => {
    loadData();
  }, [loadData]); // dependent on loadData, but that changes only once (first render, see above).

  // note: you could move loadData inside the effect to reduce some code noise. Example:
  //
  // useEffect(() => {
  //   const loadData = () => {
  //     fakeApi(1000).then(() => {
  //       setCount(count => count + 1);
  //     });
  //
  //     fakeApi(2000).then(() => {
  //       setCount(count => count + 1);
  //     });
  //   };
  //
  //   loadData();
  // }, []);

  return (
    <div>{count}</div>
  );
};

export default Count;

演示:https://codesandbox.io/s/focused-sun-0cz6u?file=/src/App.tsx