Next.js + Redux报错:Cannot read properties of null (reading 'useContext')求助
问题解决:Next.js + Redux 中 "Cannot read properties of null (reading 'useContext')" 错误
问题描述
使用Next.js和Redux Toolkit时,在用户页面调用useAppSelector读取Redux Store值时,触发错误:Cannot read properties of null (reading 'useContext'),使用原生useSelector也会出现相同错误,重装依赖后问题依旧。
错误原因
- 服务器组件误用React Hooks:你的
UsersPage定义为异步服务器组件(async () => {}),但useAppSelector基于React的useContext实现,属于客户端Hook,只能在客户端组件中使用,服务器组件不支持任何React Hooks。 - 可能缺少Redux Provider包裹:如果根布局未用
Provider包裹整个应用,客户端组件也无法访问Redux上下文,同样会触发该错误。
解决方案
步骤1:将用户页面转为客户端组件
在UsersPage顶部添加'use client';指令,移除async标识(客户端组件不能是异步函数),并调整数据获取逻辑为客户端侧执行:
'use client'; import { useAppSelector } from '@/redux/store'; import React, { useState, useEffect } from 'react' interface User { id: number; name: string; username: string; email: string; }; const UsersPage = () => { const username = useAppSelector((state) => state.auth.value.username); const [users, setUsers] = useState<User[]>([]); // 客户端侧执行数据获取 useEffect(() => { const fetchUsers = async () => { const res = await fetch( 'https://jsonplaceholder.typicode.com/users', { next: { revalidate: 10 } } ); const data = await res.json(); setUsers(data); }; fetchUsers(); }, []); return ( <> <p>当前登录用户:{username}</p> <h1>用户列表</h1> <table className="table table-bordered"> <thead> <th>姓名 | 用户名</th> <th>邮箱</th> </thead> { users.map(user => <tr key={user.id}> <td>{user.name} | @{user.username}</td> <td>{user.email}</td> </tr> )} </table> </> ) } export default UsersPage
步骤2:确保根布局用Redux Provider包裹
在Next.js的根布局文件(app/layout.tsx)中,导入Redux的Provider和你的store,将整个应用包裹起来,保证所有客户端组件能访问Redux上下文:
// app/layout.tsx import { Provider } from 'react-redux'; import { store } from '@/redux/store'; import type { Metadata } from 'next'; export const metadata: Metadata = { title: '开发者会员系统', description: '基于Next.js的会员管理系统', }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="zh-CN"> <body> <Provider store={store}>{children}</Provider> </body> </html> ); }
关键注意事项
- 只有标记
'use client';的客户端组件,才能使用useSelector/useDispatch等Redux Hooks。 - 服务器组件适合静态渲染、服务端数据预取,但无法使用客户端相关API和Hooks。
- 若需在服务器组件中获取用户状态,可将状态同步到Cookie等服务端可访问的存储中。
内容的提问来源于stack exchange,提问作者Khairul Habib
相关产品推荐
相关产品推荐

