title: MobX and Next.js (Fast Refresh)
body: <p>I can't seem to find a way to set initial checkbox state from MobX store after a fast refresh from Next.js. As soon as i refresh the page, it renders with the state i set before.</p>
  <p>For example: i check the checkbox (which has the checked/onChange routed to MobX) -&gt; Page refresh -&gt; The input persists to be checked, while the state is set to false.</p>
  <p>I've tried all the other ways to pass the observer HOC (Observer, useObserver), disabling hydration, reworking store, but to no avail.</p>
  <p>Here's the code:</p>
  <p><em>store/ThemeStore.ts</em></p>
  <pre><code>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;
  </code></pre>
  <p><em>pages/index.tsx</em></p>
  <pre><code>import React, { useEffect } from &quot;react&quot;;
  import { reaction } from &quot;mobx&quot;;
  
  import styles from &quot;@/styles/homepage.module.scss&quot;;
  import { observer } from &quot;mobx-react&quot;;
  import { useStore } from &quot;@/stores&quot;;
  
  const HomePage = observer(function () {
    const { themeStore } = useStore();
  
    useEffect(() =&gt; {
      const re = reaction(
        () =&gt; themeStore.darkTheme,
        (value) =&gt; {
          const body = document.body;
  
          if (value) {
            body.classList.remove(&quot;theme-light&quot;);
            body.classList.add(&quot;theme-dark&quot;);
          } else {
            body.classList.remove(&quot;theme-dark&quot;);
            body.classList.add(&quot;theme-light&quot;);
          }
        },
        { fireImmediately: true }
      );
      return () =&gt; {
        re();
      };
    }, []);
  
    return (
      &lt;div className={styles.container}&gt;
        &lt;main className={styles.main}&gt;
            &lt;input
              type=&quot;checkbox&quot;
              defaultChecked={themeStore.darkTheme}
              onChange={(e) =&gt; {
                themeStore.setDarkTheme(e.target.checked);
              }}
            /&gt;
        &lt;/main&gt;
      &lt;/div&gt;
    );
  });
  
  export default HomePage;
  </code></pre>
  <p><em>stores/index.tsx</em></p>
  <pre><code>import React, { ReactNode, createContext, useContext } from &quot;react&quot;;
  import { enableStaticRendering } from &quot;mobx-react&quot;;
  
  import RootStore, { RootStoreHydration } from &quot;./RootStore&quot;;
  
  enableStaticRendering(typeof window === &quot;undefined&quot;);
  
  export let rootStore = new RootStore();
  
  export const StoreContext = createContext&lt;RootStore | undefined&gt;(undefined);
  
  export const useStore = () =&gt; {
    const context = useContext(StoreContext);
    if (context === undefined) {
      throw new Error(&quot;useRootStore must be used within RootStoreProvider&quot;);
    }
  
    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 === &quot;undefined&quot;) 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 (
      &lt;StoreContext.Provider value={store}&gt;{children}&lt;/StoreContext.Provider&gt;
    );
  }
  
  </code></pre>
  <p>Thanks in advance!</p>