Next.js中useEffect无限循环:预加载器无限加载如何修复?
React预加载器无限加载问题修复
你的预加载器陷入无限加载状态,核心是两个关键问题导致的,以下是具体分析和修复方案:
问题根源
- useEffect缺少依赖数组:当前代码的
useEffect没有传递空依赖数组[],会导致组件每次渲染时重复执行事件监听的添加与移除逻辑,引发状态更新混乱。 - 未处理页面已加载的场景:如果组件挂载时页面资源已经加载完成(
window.load事件已触发),后续添加的监听永远不会执行,isLoading持续为true,加载器无法隐藏。
修复步骤
- 给
useEffect添加空依赖数组,确保逻辑仅在组件首次挂载时执行一次。 - 组件挂载时先通过
document.readyState判断页面是否已加载完成,若已完成则直接执行加载完成后的状态更新。 - 保留事件监听的清理逻辑,避免内存泄漏。
修正后的代码
'use client' import React, { useEffect, useState } from 'react'; export default function Loader() { const [isLoading, setIsLoading] = useState(true); const [isFadeClass, setFadeClass] = useState(false); useEffect(() => { const handleLoadFinish = () => { setTimeout(() => { setFadeClass(true); }, 1000); setTimeout(() => { setIsLoading(false); }, 1500); }; // 先检查页面是否已经加载完成 if (document.readyState === 'complete') { handleLoadFinish(); } else { // 未加载完成则绑定load事件监听 window.addEventListener("load", handleLoadFinish); } // 清理函数:移除事件监听 return () => { window.removeEventListener("load", handleLoadFinish); }; }, []); // 空依赖数组确保逻辑仅执行一次 return ( <> <div className={`LOADER_WRAPPER${isLoading ? "_SHOW" : ""}${isFadeClass ? " fade-effect" : ""}`}> <span className='loader'></span> </div> </> ); }
关键说明
document.readyState === 'complete':判断页面所有资源(图片、样式表等)是否加载完毕,避免错过load事件触发时机。- 空依赖数组
[]:限制useEffect仅在组件挂载时执行一次,避免重复绑定事件。 - 统一的
handleLoadFinish函数:抽离加载完成后的状态更新逻辑,不管是直接触发还是通过事件监听触发,都执行相同逻辑。
内容的提问来源于stack exchange,提问作者Siam Parvez
相关产品推荐
相关产品推荐

