如何创建仅在页面刷新后首次返回true的React Hook
实现仅在页面刷新后首次返回true的React Hook
你的核心问题在于performance.getEntriesByType('navigation')返回的导航信息在整个页面会话中是固定的,所以后续组件挂载时依然会检测到'reload'类型,导致重复返回true。要解决这个问题,我们需要结合**会话存储(sessionStorage)**来标记是否已经处理过本次刷新的状态,确保仅在刷新后的第一次交互时返回true。
最终实现代码
import { useRef, useEffect } from 'react'; import { Platform } from 'react-native'; type UseDetectPageRefreshProps = { wasPageRefreshed: boolean; }; function useDetectPageRefresh(): UseDetectPageRefreshProps { if (Platform.OS !== 'web') { return { wasPageRefreshed: false }; } // 用useRef缓存状态,避免重复计算 const wasRefreshedRef = useRef<boolean | null>(null); useEffect(() => { // 检测当前页面是否是刷新加载 const isReload = performance .getEntriesByType('navigation') .some(nav => (nav as PerformanceNavigationTiming).type === 'reload'); // 检查是否已经处理过本次刷新 const hasHandledRefresh = sessionStorage.getItem('hasHandledRefresh') === 'true'; if (isReload && !hasHandledRefresh) { wasRefreshedRef.current = true; // 标记已处理,同会话内后续挂载不再返回true sessionStorage.setItem('hasHandledRefresh', 'true'); } else { wasRefreshedRef.current = false; } }, []); return { wasPageRefreshed: wasRefreshedRef.current ?? false }; } export default useDetectPageRefresh;
关键逻辑说明
- performance检测:依然用
PerformanceNavigationTiming.type判断是否是刷新加载,这一步确保我们能识别页面刷新的场景。 - sessionStorage标记:
sessionStorage的生命周期与当前页面会话绑定,页面刷新后会自动清空。当检测到刷新且未标记过时,设置标记,后续组件挂载时读取该标记,直接返回false。 - useRef缓存:用
useRef缓存结果,避免每次组件渲染都重新计算,提升性能的同时保证状态稳定。
为什么之前的方案无效?
performance.clearResourceTimings()只能清除资源加载的计时条目,无法修改或清除导航类型的记录——导航信息是页面加载时生成的固定数据,在会话过程中不会变化,所以即使调用该方法,后续检测依然会得到'reload'类型。
内容的提问来源于stack exchange,提问作者Bruno Raphael Rocha
相关产品推荐
相关产品推荐

