疑问:显示HashLoader加载动画时,我的网站是否正在加载?
问题分析与解决方案
问题根源
你当前的代码用了**固定时长的setTimeout**控制加载动画的显示,这个定时器和网站实际的资源加载、数据请求完全无关,只是到点就强制隐藏动画,自然不会等待真实的加载过程。
解决方案1:等待页面所有静态资源加载完成
如果需要等待图片、字体、脚本等所有静态资源加载完毕再显示内容,可以监听浏览器的load事件——它会在页面所有资源加载完成后触发:
修改App.js的useEffect部分:
function App() { const [loading, setloading] = useState(true); // 初始设为true,直接显示加载动画 useEffect(() => { const handlePageLoad = () => { setloading(false); }; // 如果页面已经加载完成,直接关闭动画 if (document.readyState === 'complete') { handlePageLoad(); } else { window.addEventListener('load', handlePageLoad); // 清理监听事件,避免内存泄漏 return () => window.removeEventListener('load', handlePageLoad); } }, []); return ( <> {loading ? ( <div className="App"> <HashLoader className='loader' color={'#FF5757'} loading={loading} size={120} /> </div> ) : ( <Newhome /> )} </> ); }
解决方案2:等待组件内的异步数据加载完成
如果Newhome组件里有接口请求、异步数据获取逻辑,需要等待这些操作完成再关闭动画,可将加载状态提升到App组件,或让子组件通知父组件加载完成:
修改Newhome组件(添加加载完成回调)
import { useState, useEffect } from 'react'; function Newhome({ onLoaded }) { const [data, setData] = useState(null); useEffect(() => { // 替换为你的真实接口请求 fetch('你的接口地址') .then(res => res.json()) .then(response => { setData(response); onLoaded(); // 数据加载完成,通知父组件关闭动画 }) .catch(() => { onLoaded(); // 出错也关闭动画,避免无限加载 }); }, [onLoaded]); if (!data) return null; // 数据未加载时,不渲染内容 // 组件正常渲染内容 return ( <div>你的页面内容</div> ); } export default Newhome;
修改App组件(接收子组件的加载完成通知)
function App() { const [loading, setloading] = useState(true); return ( <> {loading ? ( <div className="App"> <HashLoader className='loader' color={'#FF5757'} loading={loading} size={120} /> </div> ) : ( <Newhome onLoaded={() => setloading(false)} /> )} </> ); }
解决方案3:结合React Suspense(懒加载场景)
如果Newhome是通过React.lazy懒加载的组件,可用React内置的Suspense配合加载动画,更符合React的加载机制:
import { Suspense, lazy } from 'react'; import HashLoader from "react-spinners/HashLoader"; import "./App.css"; // 懒加载Newhome组件 const Newhome = lazy(() => import('./COMPONENTS/Newhome')); function App() { return ( <Suspense fallback={ <div className="App"> <HashLoader className='loader' color={'#FF5757'} loading={true} size={120} /> </div> }> <Newhome /> </Suspense> ); } export default App;
内容的提问来源于stack exchange,提问作者Ankit
相关产品推荐
相关产品推荐

