MobX 和 Next.js快速刷新

问题描述

从 Next.js 快速刷新后,我似乎找不到一种方法来设置 MobX 商店的初始复选框状态。一旦我刷新页面,它就会以我之前设置的状态呈现。

例如:我选中复选框(其中已选中/onChange 路由到 MobX) -> 页面刷新 -> 输入持续被选中,而状态设置为 false。

我已经尝试了所有其他方法来通过观察者 HOC(观察者、使用观察者)、禁用水合、重新加工商店,但都无济于事。

代码如下:

store/ThemeStore.ts

import { makeAutoObservable } from 'mobx';

export type ThemeHydration = {
    darkTheme: boolean;
};

class ThemeStore {
    darkTheme = false;

    constructor() {
        makeAutoObservable(this);
    }

    setDarkTheme(value: boolean) {
        this.darkTheme = value;

    }

    hydrate(data?: ThemeHydration) {
        if (data) {
            this.darkTheme = data.darkTheme;
        }
    }
}

export default ThemeStore;

pages/index.tsx

import React,{ useEffect } from "react";
import { reaction } from "mobx";

import styles from "@/styles/homepage.module.scss";
import { observer } from "mobx-react";
import { useStore } from "@/stores";

const HomePage = observer(function () {
  const { themeStore } = useStore();

  useEffect(() => {
    const re = reaction(
      () => themeStore.darkTheme,(value) => {
        const body = document.body;

        if (value) {
          body.classList.remove("theme-light");
          body.classList.add("theme-dark");
        } else {
          body.classList.remove("theme-dark");
          body.classList.add("theme-light");
        }
      },{ fireImmediately: true }
    );
    return () => {
      re();
    };
  },[]);

  return (
    <div className={styles.container}>
      <main className={styles.main}>
          <input
            type="checkBox"
            defaultChecked={themeStore.darkTheme}
            onChange={(e) => {
              themeStore.setDarkTheme(e.target.checked);
            }}
          />
      </main>
    </div>
  );
});

export default HomePage;

stores/index.tsx

import React,{ ReactNode,createContext,useContext } from "react";
import { enableStaticRendering } from "mobx-react";

import RootStore,{ RootStoreHydration } from "./RootStore";

enableStaticRendering(typeof window === "undefined");

export let rootStore = new RootStore();

export const StoreContext = createContext<RootStore | undefined>(undefined);

export const useStore = () => {
  const context = useContext(StoreContext);
  if (context === undefined) {
    throw new Error("useRootStore must be used within RootStoreProvider");
  }

  return context;
};

function initializeStore(initialData?: RootStoreHydration): RootStore {
  const _store = rootStore ?? new RootStore();

  if (initialData) {
    _store.hydrate(initialData);
  }
  // For SSG and SSR always create a new store
  if (typeof window === "undefined") return _store;
  // Create the store once in the client
  if (!rootStore) rootStore = _store;

  return _store;
}

export function RootStoreProvider({
  children,hydrationData,}: {
  children: ReactNode;
  hydrationData?: RootStoreHydration;
}) {
  const store = initializeStore(hydrationData);

  return (
    <StoreContext.Provider value={store}>{children}</StoreContext.Provider>
  );
}

提前致谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)