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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:22:51