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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:55:26