Next.js客户端获取Cookie及getServerSideProps使用报错问题
解决方案
客户端调用getCookie首屏抛Cannot read properties of undefined错误
核心原因:Next.js首屏渲染在服务端执行,该环境不存在浏览器window/document对象,cookies-next无参调用时默认从浏览器上下文读取Cookie,服务端执行时读取目标为undefined就会触发类型错误;浏览器控制台能看到Cookie有效值,是因为hydration完成后客户端环境已正常加载,但此时首屏崩溃流程已经触发。
根据使用场景选对应修复方式:
- 仅在客户端组件中使用Cookie:不要把
getCookie调用放在组件同步渲染的顶层,将调用逻辑挪到仅客户端执行的时机,比如useEffect回调、事件回调中:
'use client' import { getCookie } from 'cookies-next' import { useEffect, useState } from 'react' export default function TargetPage() { const [cookieValue, setCookieValue] = useState<string | null>(null) useEffect(() => { // useEffect 仅在客户端hydration完成后执行,不会在服务端首屏阶段运行 const val = getCookie('your_cookie_name') setCookieValue(val as string) }, []) return <div>读取到的Cookie值:{cookieValue}</div> }
如果需要在渲染逻辑中做兼容判断,可以先加环境判断再调用:
const cookieValue = typeof window !== 'undefined' ? getCookie('your_cookie_name') : undefined
- 首屏渲染就需要用到Cookie值:直接在服务端获取Cookie后通过props传递给页面组件,避免hydration前后数据不一致。
getServerSideProps的ESLint与TypeScript报错冲突
核心原因:ESLint规则会标记没有await表达式的async函数为冗余写法,但Next.js的类型定义强制要求getServerSideProps必须是返回Promise的异步函数,二者规则存在冲突。
两种无副作用的修复方案二选一即可:
- 方案一:保留
async关键字,在函数内添加一行await Promise.resolve(),既满足TS对异步返回的类型要求,也不会触发ESLint校验报错。注意服务端调用cookies-next方法必须传入请求上下文,否则无法正常读取Cookie:
import type { GetServerSideProps } from 'next' import { getCookie } from 'cookies-next' export const getServerSideProps: GetServerSideProps = async (context) => { // 该行无额外性能损耗,仅用于适配规则 await Promise.resolve() const targetCookie = getCookie('your_cookie_name', { req: context.req, res: context.res }) return { props: { cookieValue: targetCookie ?? null } } }
- 方案二:移除
async关键字,直接用Promise.resolve包裹返回对象,同时满足两边的规则要求:
import type { GetServerSideProps } from 'next' import { getCookie } from 'cookies-next' export const getServerSideProps: GetServerSideProps = (context) => { const targetCookie = getCookie('your_cookie_name', { req: context.req, res: context.res }) return Promise.resolve({ props: { cookieValue: targetCookie ?? null } }) }
注意:服务端环境不存在浏览器Cookie API,所有
cookies-next的方法调用都必须传入对应请求的req、res上下文对象,否则会返回undefined。
内容的提问来源于stack exchange,提问作者Олег Трухан
相关产品推荐
相关产品推荐

