NextJS中使用router时useEffect依赖项相关问题咨询
NextJS官方示例未将router加入依赖,是因为旧版官方ESLint配置默认对next/router返回的实例做了exhaustive-deps规则的豁免,如果你升级了ESLint插件版本、或者使用App Router中next/navigation导出的useRouter,就会触发这条提示。你可以根据你的项目场景选择以下解决方案:
方案1:解构稳定的push方法作为依赖
useRouter返回的实例中,push等导航方法本身是引用稳定的,不会随路由参数、动态路由段变化而更新。你可以直接解构出用到的push方法,仅将它加入依赖数组即可,既满足ESLint规则,又不会触发无限循环:
const useUser = () => ({ user: null, loading: false }) export default function Page() { const { user, loading } = useUser() const { push } = useRouter() useEffect(() => { if (!(user || loading)) { push('/login') } }, [user, loading, push]) return <p>Redirecting...</p> }
方案2:服务端/中间件重定向(更推荐)
客户端useEffect重定向会存在短暂的页面闪屏问题,你可以根据你的路由模式选择更合理的重定向实现:
- Pages Router场景:在
getServerSideProps中判断鉴权状态,直接返回redirect配置即可完成服务端重定向export async function getServerSideProps(context) { const user = await getCurrentUser(context.req) if (!user) { return { redirect: { destination: '/login', permanent: false, }, } } return { props: { user } } } - App Router场景:在根目录新增
middleware.ts做全局鉴权重定向,不需要在单个页面组件内写额外逻辑。
方案3:手动禁用ESLint规则(仅作为兜底方案)
如果你确认当前依赖数组完全符合业务逻辑,也可以单行禁用这条ESLint规则,注意必须补充注释说明忽略的原因:
useEffect(() => { if (!(user || loading)) { router.push('/login') } // 仅监听user和loading状态变化触发重定向,router实例引用稳定无需加入依赖 // eslint-disable-next-line react-hooks/exhaustive-deps }, [user, loading])
内容的提问来源于stack exchange,提问作者adrian
相关产品推荐
相关产品推荐

