You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13.4结合Redux-Toolkit开发遇Hydration错误求助

问题原因分析

你遇到的Hydration错误核心原因有两个:

  1. 服务端组件直接访问全局Redux Store:Next.js 13+的服务端组件运行在服务器环境,全局Redux Store是单例模式,会导致跨请求状态污染;同时服务端渲染时的Store状态和客户端初始状态不一致,引发Hydration内容不匹配。
  2. 客户端交互逻辑混入服务端组件:搜索过滤属于客户端交互行为,不应该在服务端组件中处理,服务端组件仅负责获取初始静态数据。
解决方案

将服务端组件和客户端组件分离,服务端组件负责获取初始数据,客户端组件处理Redux状态访问和过滤逻辑。

1. 配置Redux Provider(客户端顶层)

在根布局中使用客户端组件包裹Redux Provider,确保客户端组件树能访问Store:

// app/layout.tsx
'use client';
import { Provider } from 'react-redux';
import { store } from '@/store';

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

2. 创建客户端组件处理过滤逻辑

单独抽离客户端组件,使用useSelector访问Redux状态:

// app/components/ProductListClient.tsx
'use client';
import { useSelector } from 'react-redux';
import Product from './Product';
import SearchForm from './SearchForm';
import { RootState } from '@/store';

type Props = {
  initialProducts: Product[];
};

export default function ProductListClient({ initialProducts }: Props) {
  const searchData = useSelector((state: RootState) => state.searchData.value);
  const displayProducts = searchData.length > 0 ? searchData : initialProducts;

  return (
    <>
      <SearchForm />
      <h1 className="text-2xl sm:text-3xl md:text-5xl font-bold text-center">
        DEALS OF THE DAY
      </h1>
      <div className="grid grid-cols-1 gap-y-10 gap-x-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
        {displayProducts.map((product) => (
          <Product key={product.id} product={product} />
        ))}
      </div>
    </>
  );
}

3. 修改Home服务端组件

仅保留数据获取逻辑,将数据传递给客户端组件:

// app/page.tsx
import ProductListClient from './components/ProductListClient';

export const metadata = {
  title: "Home",
  description: "Check the best deals from our store",
};

export default async function Home() {
  const response = await fetch("https://fakestoreapi.com/products", { cache: 'force-cache' });
  const initialProducts: Product[] = await response.json();

  return (
    <main className="min-h-screen max-w-7xl mx-auto px-8 xl:px-0 mt-48">
      <section className="flex flex-col space-y-12 pb-44">
        <ProductListClient initialProducts={initialProducts} />
      </section>
    </main>
  );
}
关键注意事项
  • 服务端组件禁止直接访问Redux Store,避免跨请求状态泄漏和Hydration不匹配。
  • 所有依赖客户端状态的交互逻辑(如搜索过滤)必须放在带'use client'指令的客户端组件中,使用React Redux官方hooks(useSelector/useDispatch)操作状态。

内容的提问来源于stack exchange,提问作者Alex.J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:33:16