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

Next.js+Redux Toolkit初始化state时getCookie无法取值求助

问题分析与解决方案

你遇到的核心问题是:Next.js的服务端渲染(SSR)特性导致slice初始化时无法读取到cookie。因为你的themeSlice会在服务端和客户端都执行,而服务端环境中cookies-next的getCookie/hasCookie在没有传入req/res参数的情况下,无法获取到请求中的cookie,所以始终返回undefined,初始状态就被设为light。而toggleTheme是在客户端触发的,setCookie能正常写入,但刷新页面后服务端重新初始化slice,又会回到默认的light。

下面是两种可行的解决方案:


方案一:客户端组件中初始化主题状态

1. 修改themeSlice,新增初始化reducer

先把初始状态设为默认值,新增一个setTheme方法用于手动设置主题:

import { createSlice } from "@reduxjs/toolkit"
import { setCookie } from 'cookies-next'

const initialState = {
    name: 'light' // 先设默认值,后续在客户端覆盖
}

export const Theme = createSlice({
    name: "theme",
    initialState,
    reducers: {
        toggleTheme: (state) => {
            state.name = state.name === "light" ? "dark" : "light"
            setCookie('theme', state.name)
        },
        setTheme: (state, action) => {
            state.name = action.payload
            setCookie('theme', action.payload)
        }
    }
})

export const { toggleTheme, setTheme } = Theme.actions
export default Theme.reducer

2. 在客户端入口组件中初始化主题

在_app.js或layout.tsx(App Router)的客户端组件里,用useEffect读取cookie并同步到Redux:

import { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { getCookie } from 'cookies-next'
import { setTheme } from '../slices/themeSlice'

// 如果是App Router,需要加上"use client"指令
"use client"

function MyApp({ Component, pageProps }) {
  const dispatch = useDispatch()

  useEffect(() => {
    // 仅在客户端环境读取cookie
    const savedTheme = getCookie('theme') || 'light'
    dispatch(setTheme(savedTheme))
  }, [dispatch])

  return <Component {...pageProps} />
}

export default MyApp

方案二:利用服务端预加载状态(适配SSR)

如果你需要服务端渲染时就正确渲染主题,可以用next-redux-wrapper在服务端获取cookie并传递给Redux初始状态:

1. 配置Redux Store

import { configureStore } from '@reduxjs/toolkit'
import themeReducer from './slices/themeSlice'
import { createWrapper } from 'next-redux-wrapper'
import { getCookie } from 'cookies-next'

const makeStore = (context) => {
  // 服务端环境下通过context.req获取cookie
  const initialTheme = context?.req 
    ? getCookie('theme', { req: context.req }) 
    : 'light'
  
  return configureStore({
    reducer: {
      theme: themeReducer,
    },
    preloadedState: {
      theme: { name: initialTheme || 'light' }
    }
  })
}

export const wrapper = createWrapper(makeStore)

2. 用wrapper包裹入口组件

import { wrapper } from '../store'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default wrapper.withRedux(MyApp)

这样服务端渲染时就能直接读取请求中的cookie,初始状态会和cookie值保持一致,刷新页面后也不会重置。

内容的提问来源于stack exchange,提问作者VIKESIR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:46:05