React加载动画为什么会出现内容和骨架屏同时闪烁?

司空晴文 阅读 52

我在用React做数据加载时的骨架屏过渡,但发现内容渲染和骨架屏会同时显示0.5秒,导致闪烁问题。之前用条件判断控制显示:


function ProductList() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('api/products')
      .then(res => res.json())
      .then(data => {
        setProducts(data);
        setLoading(false); // 这里直接设置loading为false
      });
  }, []);

  return (
    <div>
      {loading && <Skeleton count={4} />}
      {!loading && <ProductGrid items={products} />}
    </div>
  );
}

尝试过把loading设为’pending’|’success’状态区分,但切换时还是有重影。有没有更好的方法让过渡更平滑?感觉是状态切换时机没抓准…

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
司徒素红
这其实是渲染时机的问题,你现在的逻辑是加载完数据后立刻隐藏骨架屏并渲染内容,但 React 的渲染和 DOM 更新是异步的,所以会有一瞬间两个组件都存在。

可以优化成用 useEffect 监听 loading 状态变化,在 loading 从 true 变成 false 的时候再触发内容渲染。或者更直接一点,用一个布尔值来控制是否已经加载完成,这样可以确保内容只有在数据真正准备好之后才会渲染。

比如你可以这样改:

function ProductList() {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const [renderContent, setRenderContent] = useState(false);

useEffect(() => {
fetch('api/products')
.then(res => res.json())
.then(data => {
setProducts(data);
setLoading(false);
setRenderContent(true);
});
}, []);

return (

{loading && }
{renderContent && }

);
}


这样骨架屏隐藏和内容显示就变成两个阶段了,不会同时出现。其实这个方式就是把 loading 状态的切换和内容的渲染拆开控制,确保过渡平滑。
点赞 5
2026-02-05 11:01