Next.js移动端页面返回后加载状态未重置问题求助
问题
用Next.js搭建了一个网页,页面上有多个可跳转至其他网站的图片卡片。点击任意卡片时,会把loading状态设为true来显示加载spinner,之后浏览器会打开卡片对应的链接。但从跳转后的页面点击返回按钮时,页面仍会显示之前的加载spinner,组件也没重新渲染。这个问题只在移动端浏览器出现,桌面端表现正常。
代码如下:
<div className={`${styles["image-container"]}`} key={index}> <a href={card.card_url} onClick={()=>setLoading(true)}> <Image src={card.card_image} alt={card.alt_text} width={150} height={150} /> </a> </div>
解决方案
- 监听浏览器的
pageshow事件,在用户返回页面时重置loading状态为false - 借助Next.js的
useEffect钩子绑定事件,同时在组件卸载时清理监听
修改后的完整代码示例:
import { useEffect, useState } from 'react'; import Image from 'next/image'; // 组件内部状态与事件处理 const [loading, setLoading] = useState(false); useEffect(() => { const resetLoading = () => { setLoading(false); }; window.addEventListener('pageshow', resetLoading); // 组件销毁时移除事件监听,避免内存泄漏 return () => { window.removeEventListener('pageshow', resetLoading); }; }, []); // 原有卡片渲染逻辑 <div className={`${styles["image-container"]}`} key={index}> <a href={card.card_url} onClick={()=>setLoading(true)}> <Image src={card.card_image} alt={card.alt_text} width={150} height={150} /> </a> </div>
问题根源
移动端浏览器普遍启用了后退缓存(bfcache),当用户点击返回按钮时,页面会直接从缓存中恢复,不会重新执行组件的初始化流程,也不会触发依赖为空数组的useEffect。这就导致之前设置的loading状态被缓存保留,返回后依然显示spinner。
通过监听pageshow事件,能在页面从缓存中恢复显示时,强制重置loading状态,解决这个问题。
内容的提问来源于stack exchange,提问作者Bilal Mohammad
相关产品推荐
相关产品推荐

