【问题标题】:Does Redux still makes sense with NextJS 13 App directory?Redux 对 NextJS 13 App 目录是否仍然有意义?
【发布时间】:2022-11-19 19:31:08
【问题描述】:

随着新的 NextJS 13 引入 app 目录,redux 仍然有意义吗?

已经可以将 redux 提供程序包装在客户端组件根据下一个文档。但是与 redux 共享状态将如何影响 Next 性能和优化?

接下来的文档要求在需要数据的地方获取数据,而不是向下传递组件树。请求将是automatically deduped

我对 Redux 的使用是控制我希望保持一致的应用程序的某些部分。

例如:如果我更改用户名,我希望它反映在需要该数据的整个应用程序中。

【问题讨论】:

  • 我不会假装完全掌握了新的 NextJS 13 组件模型及其组件树,但我不得不想象它归结为每个组件对更改的监控实现,例如您的用户名示例。如果组件中的某个值有一个活跃的观察者,并且该值已更新,我希望该组件会自动更新受影响的树。不过,样本中有些东西似乎比这更接近魔法,所以我只是将其作为评论发布,等待更多知情人士提出。

标签: reactjs redux next.js react-redux


【解决方案1】:

我最近开始使用 NextJS 并且我遇到了同样的问题,经过一些研究我已经设法让它工作而不用 ReduxProvider 包装每个客户端组件。

根据 NextJS 团队提供的文档,建议 Providers 客户端组件为任何其他客户端组件提供上下文。

更多详情:NextJS Context documentation

第 1 步:在 app/providers 中创建一个 Provider 组件(确保这是一个客户端组件)

 "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>
    </>
  );
}

创建一个 redux 提供者组件。

"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>;
}

在 RootLayout 组件中使用您的提供者组件。 (应用程序/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>
  );
}

【讨论】:

    猜你喜欢
    • 2023-02-11
    • 2022-11-24
    • 2014-01-02
    • 2011-08-24
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多