Next.js切换页面时_app.js定义的共享变量重置问题
问题根因
跨页面切换后state重置的核心原因是你使用原生<a>标签做站内跳转,这种跳转方式会触发浏览器全量页面刷新,整个React应用实例(包括_app.js中存储的所有state)会被完全销毁后重新加载,state自然会回到初始值0。
除此之外你的代码还存在4个会导致功能异常的隐藏bug:
_app.js中重复声明了setTestVariable函数,且函数内部调用了从未定义的setLocalVariable,存在命名冲突和未定义方法错误- 页面中按钮的
onClick事件直接传入setTestVariable(1),页面渲染阶段就会立即执行该方法,而非点击时触发 - About页的跳转路径写为
/about.js,Next.js页面路由不需要带文件后缀,正确路径为/about - 页面中使用了
Head组件但未从next/head中导入,运行时会直接抛出组件未定义错误
修复方案
1. 解决页面跳转state重置问题
Next.js Pages Router下的站内跳转必须使用内置的Link组件,走客户端路由切换,不会触发全量页面刷新,_app.js中存储的全局state才会被持续保留,禁止使用原生<a>标签做站内页面跳转。
2. 修复_app.js代码
删除重复声明的setTestVariable方法,直接将useState生成的原生setter透传给页面组件即可,修复后代码:
import { useState } from 'react'; const CustomApp = ({ Component, pageProps }) => { const [testVariable, setTestVariable] = useState(0) return ( <Component {...pageProps} testVariable={testVariable} setTestVariable={setTestVariable} /> ); } export default CustomApp
3. 修复页面组件代码
首先导入缺失的Head和Link组件,替换原生a标签为Link组件,修正跳转路径,给onClick事件包一层箭头函数避免渲染时自动执行。
如果使用Next.js 12及更早版本,Link组件内部需要嵌套a标签承载样式属性,修复后的index.js代码如下:
import { useEffect } from 'react' import Head from 'next/head' import Link from 'next/link' import 'bulma/css/bulma.css' import styles from '../styles/Home.module.css' const Home = ({ testVariable, setTestVariable }) => { return ( <div id={styles.outerDiv}> <Head> <title>My Next.Js Page</title> <meta name="description" content="A Next.js application" /> </Head> <div id={styles.navBar}> <Link href="/"> <a id={styles.navLink}> <h3>Home</h3> </a> </Link> <Link href="/about"> <a id={styles.navLink}> <h3>About</h3> </a> </Link> </div> <div id={styles.content} className="content"> <br/> <h2>Test Variable: {testVariable}</h2> <button id={styles.incrementButton} onClick={() => setTestVariable(1)} > Set Test Variable to 1 </button> </div> </div> ) } export default Home
about.js页面按照相同逻辑修改即可。
补充说明
_app.js中存储的本地state仅在客户端路由跳转时会被保留,如果需要浏览器刷新后也保留变量值,不要存在组件本地state中,可以搭配localStorage/sessionStorage做持久化,或者使用Zustand、Redux等全局状态管理库搭配持久化插件实现。
内容的提问来源于stack exchange,提问作者Noah B
相关产品推荐
相关产品推荐

