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

React Hooks中isLoading加载状态对应UI出现两次渲染问题

问题描述

我有一个isLoading的useState变量,测试时故意注释了setIsLoading(false)语句来强制展示加载UI,却发现加载UI渲染了两次,有人知道是什么原因吗?
加载状态展示截图

API调用代码

export default function App() { 
  const [upcoming, setUpcoming] = useState([]); 
  const [isLoading, setIsLoading] = useState(false);

 useEffect(() => {
    const fetchUpcoming = async () => {
      setIsLoading(true);

      const res = await fetch(
        "https://api.themoviedb.org/3/movie/upcoming?api_key={API_KEY}&language=en-US&page=1"
      );
      const data = await res.json();
      const results = data.results;

      setUpcoming(results);
      // setIsLoading(false);
    };

    fetchUpcoming();
  }, []);

return (
    <div className="App">
      <Recommendations title={"Upcoming"} data={upcoming} loading={isLoading} />
    </div>
  );
}

渲染结果组件代码

export default function Recommendations({ title, data, loading }) {
  return (
    <div className="recommendationSection">
      <h3>{title}</h3>
      {loading ? (
        <h3>Loading...</h3>
      ) : (
        data.map((movie) => {
          return (
            <div className="banner" key={movie.title}>
              <img
                src={
                  movie.poster_path
                    ? `https://image.tmdb.org/t/p/original/${movie.poster_path}`
                    : "https://www.genius100visions.com/wp-content/uploads/2017/09/placeholder-vertical.jpg"
                }
                alt={movie.title}
              />
            </div>
          );
        })
      )}
    </div>
  );
}

原因说明

  • 代码本身的两次状态更新触发了两次加载UI渲染,完整流程如下:
    1. 组件首次渲染时,isLoading初始值为false,不会展示加载UI
    2. useEffect执行后先调用setIsLoading(true),触发第一次重渲染,此时isLoading为true,第一次渲染出加载UI
    3. 异步请求完成后调用setUpcoming(results)更新列表数据,触发第二次重渲染,由于你注释了setIsLoading(false),isLoading仍然为true,第二次渲染出加载UI
  • 如果你使用的是React 18开发环境且开启了严格模式(<StrictMode>),还会多一轮重复执行:严格模式下会模拟「组件挂载-卸载-重新挂载」的流程来校验副作用逻辑,你的useEffect会完整执行两次,也会导致加载UI多渲染两次,这个问题在生产环境会自动消失。

临时测试方案

如果只是想测试加载UI的展示效果,可以直接把isLoading的初始值设为true,不需要走异步请求流程,也不会出现重复渲染的问题;也可以临时注释掉项目根组件外层的<StrictMode>标签,关闭开发环境的重复挂载逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 08:15:04