reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.69k stars 1.17k forks source link

setting up redux toolkit with Next 14.0.1 #3842

Closed cforcross closed 11 months ago

cforcross commented 11 months ago

Below are my pakages

and the logs

 ⚠ Fast Refresh had to perform a full reload due to a runtime error.
 ⨯ node_modules\react-redux\es\components\Provider.js (25:28) @ Provider
 ⨯ TypeError: (0 , _utils_useIsomorphicLayoutEffect__WEBPACK_IMPORTED_MODULE_3__.useIsomorphicLayoutEffect) is not a function
    at stringify (<anonymous>)
null
 ⨯ node_modules\react-redux\es\components\Provider.js (25:28) @ Provider
 ⨯ TypeError: (0 , _utils_useIsomorphicLayoutEffect__WEBPACK_IMPORTED_MODULE_3__.useIsomorphicLayoutEffect) is not a function
    at stringify (<anonymous>)
digest: "3258720864"
null

below is the setup for redux toolkit in my layout.tsx

type ReduxProviderProps = {
  children: React.ReactNode;
};

function ReduxProvider({ children }: ReduxProviderProps) {
  return <Provider store={store}>{children}</Provider>;
}
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (

    <html lang="en">
      <ReduxProvider>

      <body className={inter.className}>

       {children}

      </body>
      </ReduxProvider>
    </html>

  );
}

As you can see above to the best of my knowledge, everything has been setup correctly and i've been through every resource i could find on the internet to put this all together.

Now alternative if i take out the ReduxProvider and put in a separate file to then import into the layout.tsx

type ReduxProviderProps = {
  children: React.ReactNode;
};

function ReduxProvider({ children }: ReduxProviderProps) {
  return <Provider store={store}>{children}</Provider>;
}

i get the following error next-2 and this are the logs

 ⨯ ./store/ReduxProvider.ts
Error:
  × Expected '>', got 'store'
    ╭─[C:\Users\cross\Desktop\savvyshopper\store\ReduxProvider.ts:8:1]
  8 │ };
  9 │
 10 │ function ReduxProvider({ children }: ReduxProviderProps) {
 11 │   return <Provider store={store}>{children}</Provider>;
    ·                    ─────
 12 │ }
    ╰────

and on the browser when it compiles i get next-3

None of this really makes any sense to me.Thanks appreciate the help

EskiMojo14 commented 11 months ago

./store/ReduxProvider.ts

If you're using JSX, you need to use the tsx file extension.

cforcross commented 11 months ago

./store/ReduxProvider.ts

If you're using JSX, you need to use the tsx file extension.

oooh yeah yeah yeah 🤦‍♂️🤦‍♂️ u right!!!!!!!!.. thanks

SergSvet87 commented 11 months ago

An hour of joy! The same error occurs, I use nextjs 14.0.1 without typescript ⨯ node_modules\react-redux\es\components\Provider.js (25:28) @ Provider ⨯ TypeError: (0 , _utils_useIsomorphicLayoutEffect__WEBPACK_IMPORTED_MODULE_3__.useIsomorphicLayoutEffect) is not a function at stringify () digest: "3269313807" null

selimdev00 commented 11 months ago

Same issue here:

⨯ node_modules\react-redux\es\components\Provider.js (25:28) @ Provider
⨯ TypeError: (0 , _utils_useIsomorphicLayoutEffect__WEBPACK_IMPORTED_MODULE_3__.useIsomorphicLayoutEffect) is not a function
    at stringify (<anonymous>)
null

I guess it is issue related with packages (maybe version mismatch), but I have no idea how to fix it

{
  "name": "visual-lab-client",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@ant-design/cssinjs": "^1.17.0",
    "@codemirror/lang-markdown": "^6.2.2",
    "@codemirror/lang-python": "^6.1.3",
    "@reduxjs/toolkit": "^1.9.5",
    "antd": "^5.9.0",
    "axios": "^1.5.1",
    "codemirror": "^6.0.1",
    "framer-motion": "^10.16.4",
    "js-cookie": "^3.0.5",
    "next": "^14.0.1",
    "promise": "^8.3.0",
    "react": "18.2.0",
    "react-arborist": "^3.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.46.1",
    "react-icons": "^4.11.0",
    "react-markdown": "^9.0.0",
    "react-redux": "^8.1.2",
    "uuid": "^9.0.1"
  },
  "devDependencies": {
    "@tailwindcss/typography": "^0.5.10",
    "@types/node": "20.8.10",
    "autoprefixer": "^10.4.15",
    "eslint": "^8.48.0",
    "eslint-config-next": "13.4.19",
    "eslint-config-prettier": "^9.0.0",
    "postcss": "^8.4.29",
    "prettier": "^3.0.3",
    "sass": "^1.66.1",
    "tailwindcss": "^3.3.3",
    "use-resize-observer": "^9.1.0"
  }
}

I am using app router and redux Provider in Root Layout:

import { Provider } from 'react-redux';
import { store } from '@/store';

import { ConfigProvider } from 'antd';
import theme from '@/theme/default';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <title>Visual lab</title>
      </head>
      <body>
        <Provider store={store}>
          <ConfigProvider theme={theme}>{children}</ConfigProvider>
        </Provider>
      </body>
    </html>
  );
}
markerikson commented 11 months ago

You can't use those in a root layout as far as I know, because that's a Server Component and not a Client Component. You can only use hooks in Client Components, and the React-Redux <Provider> uses hooks internally. So, it needs to go into a Client Component.

selimdev00 commented 11 months ago

You can't use those in a root layout as far as I know, because that's a Server Component and not a Client Component. You can only use hooks in Client Components, and the React-Redux <Provider> uses hooks internally. So, it needs to go into a Client Component.

Yes, I can agree, as soon as I added 'use client' line to the top of layout.jsx (root layout), error has gone :)

So it looks like this by now

'use client';

import '@/assets/scss/main.scss';

import { ConfigProvider } from 'antd';
import { StyleProvider } from '@ant-design/cssinjs';
import theme from '@/theme/default';

import { Provider } from 'react-redux';
import { store } from '@/store';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <title>Visual lab</title>
        <script src='https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js'></script>
      </head>
      <body>
        <Provider store={store}>
          <ConfigProvider theme={theme}>
            <StyleProvider hashPriority={'high'}>{children}</StyleProvider>
          </ConfigProvider>
        </Provider>
      </body>
    </html>
  );
}

You can find better solution here: https://www.linkedin.com/pulse/using-redux-nextjs-13-app-router-antematter

kamit6337 commented 7 months ago

my clarification after finding the bug and solve it.

You can't use Provider provided by react-redux directly in any layout.jsx because Provider is a client component under the hood so it won't work in Server component layout.jsx like this.

So, how can I use it ?

Here, it the solution

"use client";

import store from "@redux/store";
import { Provider } from "react-redux";

const ReactReduxProvider = ({ children }) => {
  return <Provider store={store}>{children}</Provider>;
};

export default ReactReduxProvider;

`

then

import "./globals.css";
import { Poppins } from "next/font/google";
import ReactReduxProvider from "@providers/ReactReduxProvider";

// If loading a variable font, you don't need to specify the font weight
const poppins = Poppins({
  subsets: ["latin"],
  display: "swap",
  weight: "400",
});

export const metadata = {
  title: "VwFlex",
  description: "On Demand Movies and Tv Shows",
};

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={poppins.className}>
      <body className="w-full">
        <ReactReduxProvider>{children}</ReactReduxProvider>
      </body>
    </html>
  );
}
phryneas commented 7 months ago

Yes, we show that in our docs: https://redux.js.org/usage/nextjs#providing-the-store