vercel / next.js

The React Framework
https://nextjs.org
MIT License
122.63k stars 26.25k forks source link

NextJS13 version mobx issue #50638

Open linmengdun opened 1 year ago

linmengdun commented 1 year ago

Verify canary release

Provide environment information

Nextjs13 version does not support mobx react, prompt mobx react lite requires React with Hooks support

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true)

Link to the code that reproduces this issue or a replay of the bug

blalba

To Reproduce

Nextjs13 version does not support mobx react, prompt mobx react lite requires React with Hooks support

Describe the Bug

Nextjs13 version does not support mobx react, prompt mobx react lite requires React with Hooks support

Expected Behavior

Nextjs13 version does not support mobx react, prompt mobx react lite requires React with Hooks support

Which browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

next start

BuddhiAbeyratne commented 1 year ago

We've been using next with Mobx on next 13 for a while

This might be you using mobx with server side functions.

there's no code block or Min reproduction repo so its a bit hard to help you

Besuf commented 1 year ago

We've been using next with Mobx on next 13 for a while

This might be you using mobx with server side functions.

there's no code block or Min reproduction repo so its a bit hard to help you

Could you please share a basic integration template for MobX with Next.js13 using app-directory? The official example provided seems to be using the previous pages-directory routing. Thanks!

HaimAbeles commented 9 months ago

any solution please?

adel0559 commented 8 months ago

We've been using next with Mobx on next 13 for a while This might be you using mobx with server side functions. there's no code block or Min reproduction repo so its a bit hard to help you

Could you please share a basic integration template for MobX with Next.js13 using app-directory? The official example provided seems to be using the previous pages-directory routing. Thanks!

We managed to get mobx working reasonably well with app directory. This is what our store provider looks like:

storeProvider.js

"use client"
import React from "react";
import { MobXProviderContext } from "mobx-react";
import { enableStaticRendering } from "mobx-react-lite";
import { getLayoutData } from "@/queries/layout/getLayoutData";
import { getData } from "@/utils/getData";
import { Store } from "./Store";

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

let store;

export async function getStores() {
  if(typeof window !== 'undefined' && store) store = store;
  else {
    const layoutData = getLayoutData();
    const [layout] = await Promise.all([getData(layoutData, 2000)()]);
    store = new Store({
      menus: layout.menus.menus,
    });
  }
  return store;
};

export const StoreWrapper = ({
  children
}) => {
  const [initData, setInitData] = React.useState(false);
  React.useEffect(() => {
    async function getData() {
      store = await getStores();
      setInitData(true);
    }
    getData();
    if(store) store.onMount();
    return () => store.onUnmount();
  }, [initData]);
  if(!store) return (<></>);
  return (
    <MobXProviderContext.Provider value={store}>
      {children}
    </MobXProviderContext.Provider>
  );
}

And this is the root layout file: layout.tsx

import "@/styles/styles.scss";
import { StoreWrapper } from "@/stores/StoreProvider";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className="html">
      <body>
        <StoreWrapper>
          {children}
        </StoreWrapper>
      </body>
    </html>
  );
}

In this case we are fetching some data from the server to initialize our stores which is probably not necessary in most cases. The Store file contains initialization of all stores along with hydration.

dissin101 commented 8 months ago

Who can show fully example, please?

BleddP commented 8 months ago

In my case, I got Next.js 13 working with Mobx, using it in client components ('use client'), but the observer was not re-rendering components on mobx state change.

I had to add a custom babel config to get it working:

create a .babelrc in the root of your project and add:

{
    "presets": ["next/babel"],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": false }]
    ],
    // Babel >= 7.13.0 (https://babeljs.io/docs/en/assumptions)
    "assumptions": {
      "setPublicClassFields": false
    }
  }

And install those dependencies. Now the observer works, but there's one more problem: This disables the Next.js font optimization: https://nextjs.org/docs/messages/babel-font-loader-conflict

So in the end we just switched to the Context API as it seems to work a bit better.

mawaisismail commented 7 months ago

can someone show full example with next app route ?