You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建仅在页面刷新后首次返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:33:14