Next.js App目录下Zustand使用next/router导航报错求解决方案
解决Next.js App Router + Zustand路由跳转问题
你遇到的问题是因为Next.js App Router和Pages Router的路由API不兼容:App Router不再支持next/router的全局Router对象,且默认文件是服务器组件,直接导入Router会在服务器端执行,导致找不到路由实例。下面是几种可行的解决方案:
方案1:将跳转逻辑移到客户端组件(推荐,解耦store和路由)
修改Zustand store,只处理数据逻辑,跳转交给使用store的客户端组件:
// my zustand store import create from 'zustand' const store = (set, get) => ({ // 你的状态定义 gameData: null, startGame: async () => { // 执行数据请求 const res = await fetch('/api/start-game') const data = await res.json() // 更新状态 set({ gameData: data }) }, }) const useStore = create(store) export default useStore;
在客户端组件中(需添加'use client'指令),使用next/navigation的useRouter处理跳转:
'use client' import { useRouter } from 'next/navigation' import useStore from '@/stores/myStore' export default function StartGameButton() { const router = useRouter() const startGame = useStore(state => state.startGame) const handleStart = async () => { await startGame() router.push('/gamePage') } return <button onClick={handleStart}>开始游戏</button> }
方案2:在Zustand store中直接使用客户端路由API
给Zustand store文件添加'use client'指令(标记为客户端组件),然后改用next/navigation的useRouter钩子:
'use client' import { useRouter } from 'next/navigation' import create from 'zustand' const store = (set, get) => { const router = useRouter() return { // 你的状态定义 gameData: null, startGame: async () => { // 执行数据请求 const res = await fetch('/api/start-game') const data = await res.json() set({ gameData: data }) // 执行跳转 router.push('/gamePage') }, } } const useStore = create(store) export default useStore;
方案3:通过回调函数传递跳转逻辑
如果希望store完全不依赖路由,可以将跳转逻辑作为回调参数传给store的action:
// my zustand store import create from 'zustand' const store = (set, get) => ({ // 你的状态定义 gameData: null, startGame: async (onSuccess) => { // 执行数据请求 const res = await fetch('/api/start-game') const data = await res.json() set({ gameData: data }) // 调用回调执行跳转 onSuccess?.() }, }) const useStore = create(store) export default useStore;
在客户端组件中:
'use client' import { useRouter } from 'next/navigation' import useStore from '@/stores/myStore' export default function StartGameButton() { const router = useRouter() const startGame = useStore(state => state.startGame) const handleStart = () => { startGame(() => router.push('/gamePage')) } return <button onClick={handleStart}>开始游戏</button> }
内容的提问来源于stack exchange,提问作者frost2709
相关产品推荐
相关产品推荐

