You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useEffect结合async时,isLoading状态为何未被批量更新?

React中async函数里的状态更新为何能立即显示Loading?

核心原因是await会打断同步执行流程,让React无法批量处理第一次的状态更新,具体执行逻辑如下:

  1. 组件挂载后,useEffect调用fetchRepos函数,首先执行setIsLoading(true)。
  2. 接下来遇到await fetch(...)——此时JavaScript会暂停当前async函数的执行,把控制权交还给浏览器事件循环。
  3. React检测到当前同步代码已经暂停,没有后续的同步状态更新待处理,就会立即执行setIsLoading(true)对应的状态更新,触发组件重新渲染,因此JSX能获取到isLoading=true,显示“Loading...”文本。
  4. 等GitHub API请求完成后,await恢复async函数的执行,接着执行setIsLoading(false),这时候又会触发一次渲染,切换显示“Done!”。

总结:React的批量更新仅在同步执行的代码块内生效,一旦遇到异步中断(比如await、setTimeout、Promise.then),之前的状态更新会被立即处理,不会等到函数完全结束。

举个反例,如果去掉await改成同步代码:

async function fetchRepos() {
  setIsLoading(true);
  setIsLoading(false); // 同步执行两次状态更新
}

此时React会批量处理这两次更新,只会渲染最后一次的false,你就看不到Loading状态了。

你的完整代码:

<div id="root"></div>
<script crossorigin src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script type="text/babel">
const { createRoot } = ReactDOM;
const { StrictMode, useEffect, useState } = React;

function App() {
    const [isLoading, setIsLoading] = useState(false);
    const [repos, setRepos] = useState([]);

    useEffect(() => {
        async function fetchRepos() {
            setIsLoading(true);

            const reposFetch = await fetch("https://api.github.com/users/OthmaneNissoukin/repos");
            const data = await reposFetch.json();

            setIsLoading(false);
        }
        fetchRepos();
    }, []);

    return (
        <div className="App">
            <h1>Hello CodeSandbox</h1>
            {isLoading ? <h2>Loading...</h2> : <div>Done!</div>}
        </div>
    );
}

const root = createRoot(document.getElementById("root"));
root.render(<StrictMode><App /></StrictMode>);
</script>

内容的提问来源于stack exchange,提问作者Othmane NISS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:29