如何在Next.js新项目中配置MobX实现全局状态共享?
解决Next.js App Router中MobX多组件共享单例Store的问题
1. 创建单例Store实例
不要直接导出Store类,而是导出已实例化的单例,确保所有组件导入的是同一个实例:
// stores/authStore.js import { makeAutoObservable } from "mobx"; class AuthStore { authData = null; constructor() { // 自动将属性和方法转为可观察/可操作 makeAutoObservable(this); } // 定义状态操作方法 setAuthData(data) { this.authData = data; } clearAuthData() { this.authData = null; } } // 导出全局唯一的单例实例 export const authStore = new AuthStore();
2. 在客户端组件中封装MobX Provider
Next.js App Router的根layout默认是服务器组件,无法直接使用React Context,所以需要创建专门的客户端Provider组件:
// app/providers.jsx "use client"; // 必须标记为客户端组件 import { Provider } from "mobx-react-lite"; import { authStore } from "@/stores/authStore"; export function Providers({ children }) { // 将单例Store传入Provider,供全局子组件访问 return ( <Provider authStore={authStore}> {children} </Provider> ); }
3. 在根Layout中引入Provider
用Providers组件包裹根Layout的所有内容,确保整个应用都能访问到Store:
// app/layout.js import { Providers } from "./providers"; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <Providers>{children}</Providers> </body> </html> ); }
4. 封装自定义Hook获取Store
封装自定义Hook简化子组件获取Store的流程:
// hooks/useAuthStore.js "use client"; import { useContext } from "react"; import { MobXProviderContext } from "mobx-react-lite"; export function useAuthStore() { const stores = useContext(MobXProviderContext); return stores.authStore; }
5. 在客户端组件中使用Store
所有使用Store的组件必须标记为客户端组件,并用observer包裹以实现响应式渲染:
// app/page.js "use client"; import { useAuthStore } from "@/hooks/useAuthStore"; import { observer } from "mobx-react-lite"; // 用observer包裹,监听Store状态变化 const Home = observer(() => { const authStore = useAuthStore(); return ( <div> <h1>MobX状态共享测试</h1> {authStore.authData ? ( <p>已登录:{authStore.authData.username}</p> ) : ( <p>未登录</p> )} <button onClick={() => authStore.setAuthData({ username: "测试用户" })}> 模拟登录 </button> <button onClick={() => authStore.clearAuthData()}> 退出登录 </button> </div> ); }); export default Home;
关键注意事项
- 客户端组件限制:所有使用Store、Provider、
observer的组件必须添加"use client"指令,服务器组件无法访问客户端状态管理工具。 - 单例唯一性:确保所有组件导入的是
authStore实例而非AuthStore类,避免重复创建实例导致状态重置。 - 响应式渲染:必须用
observer包裹使用Store的组件,否则Store状态更新时组件不会自动重新渲染。
内容的提问来源于stack exchange,提问作者rai-dev
相关产品推荐
相关产品推荐

