Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Redux still makes sense with NextJS 13 App directory?

With the new NextJS 13 introducing the app directory, would redux still make sense?

It's already possible to wrap redux providers around a Client Component as per next docs. But how would sharing states with redux impact Next performance and optmization?

Next docs ask to fetch data where the data is needed instead of passing down the component tree. Request will be automatically deduped.

My usage for Redux would be to control certain pieces of the application that I want to be consistent.

E.g: If I change an user name I want that reflected in the whole application where that data is needed.

like image 383
Luna Avatar asked Sep 03 '25 04:09

Luna


2 Answers

I recently started using NextJS and I had the same problem, after a bit of a research I have managed to get it working without wrapping each client component with a ReduxProvider.

Following the documentation given by the NextJS team it is suggested to a Providers client component which will give context to any other client components.

More details here: NextJS Context documentation

step 1: Create a Provider component in app/providers (make sure this is a client component)

 "use client";

import { useServerInsertedHTML } from "next/navigation";
import { CssBaseline, NextUIProvider } from "@nextui-org/react";
import { PropsWithChildren } from "react";
import ReduxProvider from "./redux-provider";

type P = PropsWithChildren;

export default function Providers({ children }: P) {
  useServerInsertedHTML(() => {
    return <>{CssBaseline.flush()}</>;
  });

  return ( // you can have multiple client side providers wrapped, in this case I am also using NextUIProvider
    <>
      <ReduxProvider>
        <NextUIProvider>{children}</NextUIProvider>
      </ReduxProvider>
    </>
  );
}

create a redux provider component.

"use client";

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

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

Use your provider component within your RootLayout component. (app/layout.tsx)

import Header from "./components/organisms/Header/Header";
import { PropsWithChildren } from "react";
import Footer from "./components/molecules/Footer/Footer";
import Providers from "./providers/Providers";
import MyBasketTab from "./components/organisms/MyBasketTab/MyBasketTab";

type Props = PropsWithChildren;

export default function RootLayout({ children }: Props) {
  return (
    <html lang="en">
      <head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </head>
      <body>
        <Providers>
          <Header />
          {children}
          <Footer />
          <MyBasketTab /> // this client component can now fully use the redux hooks and access the store.
        </Providers>
      </body>
    </html>
  );
}

"use client";

import styles from "./MyBasketTab.module.css";
import { useAppSelector } from "../../../redux/hooks/hooks";

export default function MyBasketTab() {
  const isBasketSideMenuOpened = useAppSelector(
    (x) => x.basket.isBasketSideMenuOpened
  );

  return (
    <div
      className={`${styles.container} ${
        !isBasketSideMenuOpened ? styles.opened : styles.closed
      }`}
    >
      <p>My Basket</p>
    </div>
  );
}
like image 63
Konrad Avatar answered Sep 05 '25 00:09

Konrad


The main focus of server components is to send minimum javascript code to the browser so the browser will have less code to parse and it will display the content quicker. In the case of redux state management, we were populating the state on the server, sending the store and related code to the browser and the browser was hydrating in other words it was synchronizing the server store with the client code. Hydration is a very expensive operation. we were technically recreating a new store on the client. Every time user visits a page with server-side functions, HYDRATE action was triggered and a new store was created. Imagine you have a very large application and applying hydration would slow down your app drastically.

With the app directory redux store, less code will be sent to the browser and I believe only the store that needed use client components will be hydrated (as of now we cannot set next-redux-wrapper in app directory. I think the default redux package will be redux-toolkit). this will increase the performance. Although marking some components as clients or some as servers does not seem nice, but the overall goal is to increase performance. And app directory is still in beta, as time goes by, they will make it better.

like image 28
Yilmaz Avatar answered Sep 04 '25 23:09

Yilmaz