Next.js中useRouter配合useEffect页面刷新时条件满足仍跳转问题
问题原因
- React Context 属于内存级运行时状态,页面刷新会清空内存中存储的所有Context值,如果你没有将
amount做持久化存储(如localStorage、sessionStorage),刷新后amount默认会恢复为初始空值。 - 当前
useEffect未添加依赖数组,每次组件渲染都会执行,且没有过滤初始化阶段:页面刷新后首次渲染组件时,Context还未完成初始化、Next.js路由也可能未就绪,此时拿到的amount是空值,会直接触发重定向,等后续amount被正确赋值时页面已经跳转到页面1了。
修复步骤
1. 给Context添加持久化逻辑
修改Context的Provider组件,将amount同步到本地存储,刷新时从本地存储读取初始值,同时添加初始化完成状态标识:
// AppContext 对应的Provider组件示例 import { useState, useEffect } from 'react'; import AppContext from './AppContext'; export const AppProvider = ({ children }) => { const [amount, setAmount] = useState(() => { // 服务端渲染阶段避免访问window报错 if (typeof window !== 'undefined') { const savedAmount = localStorage.getItem('app_amount'); return savedAmount ? JSON.parse(savedAmount) : null; } return null; }); // 标识Context是否完成初始化 const [isContextReady, setIsContextReady] = useState(false); // 初始化完成后修改状态 useEffect(() => { setIsContextReady(true); }, []); // amount变化时同步到localStorage useEffect(() => { if (amount !== null) { localStorage.setItem('app_amount', JSON.stringify(amount)); } }, [amount]); return ( <AppContext.Provider value={{ amount, setAmount, isContextReady }}> {children} </AppContext.Provider> ); };
2. 修改页面2的重定向逻辑
给useEffect添加依赖,增加初始化状态、路由就绪状态的判断,避免初始阶段误判:
import { useEffect, useContext } from "react"; import { useRouter } from "next/router"; import AppContext from "../context/AppContext"; const PageTwo = () => { const { amount, isContextReady } = useContext(AppContext); const router = useRouter(); useEffect(() => { // Context未初始化完成、路由未就绪时不执行重定向逻辑 if (!isContextReady || !router.isReady) return; if (!amount) { router.push("/page-1"); } }, [amount, isContextReady, router]); // 初始化阶段展示加载态,避免页面内容闪屏 if (!isContextReady) return <div>加载中...</div>; return ( // 原有页面逻辑 ... ); };
补充说明
如果你不需要持久化存储amount,可以接受刷新页面后重置状态,那只需要在页面2的重定向逻辑里添加初始化状态判断即可,不需要修改Context的持久化逻辑。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

