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

Next.js 14中Redux Toolkit与Server Actions兼容方案咨询

问题核心

useAppDispatch 是React客户端专属钩子,完全无法在Server Actions中使用——Server Actions运行在服务端环境,没有React客户端上下文(包括客户端Redux Store实例),直接调用必然报错。你的代码错误就在于违反了React钩子的使用规则,且混淆了服务端/客户端的运行边界。

可行解决方案

根据你的需求,提供三种落地思路:

1. 直接在Server Actions中处理服务端逻辑(推荐)

Server Actions本身就是服务端异步操作载体,无需借助Redux Dispatch,直接编写数据库/数据源操作逻辑即可:

"use server";
import { createProduct } from "@/app/schema/model.schema";
import { revalidatePath } from "next/cache";
// 导入你的数据库客户端(比如Prisma、Drizzle等)
import { db } from "@/app/db";

export const adminCreateProduct = async (data: createProduct) => {
  try {
    // 直接在服务端执行创建操作
    const newProduct = await db.product.create({
      data: data,
    });

    revalidatePath("/");
    return newProduct;
  } catch (error) {
    console.error(error);
    throw new Error("Internal Error");
  }
};

2. 复用Redux Thunk中的业务逻辑

如果想保留createProductModel里的业务逻辑,可将核心逻辑从Thunk中抽离为独立的服务端可调用函数,再在Server Actions中调用:

抽离业务逻辑(modelService.ts)

import { createAsyncThunk } from "@reduxjs/toolkit";
import { db } from "@/app/db";

// 抽离服务端可复用的核心逻辑
export const createProductInDB = async (data: createProduct) => {
  return await db.product.create({ data });
};

// 原Thunk继续用于客户端状态更新
export const createProductModel = createAsyncThunk(
  "products/create",
  async (data: createProduct) => {
    return await createProductInDB(data);
  }
);

在Server Actions中调用抽离的函数

"use server";
import { createProduct } from "@/app/schema/model.schema";
import { revalidatePath } from "next/cache";
import { createProductInDB } from "@/app/store/slices/model/modelService";

export const adminCreateProduct = async (data: createProduct) => {
  try {
    const newProduct = await createProductInDB(data);
    revalidatePath("/");
    return newProduct;
  } catch (error) {
    console.error(error);
    throw new Error("Internal Error");
  }
};

3. 客户端调用Server Actions后同步Redux状态

如果需要更新客户端Redux Store,可在客户端组件调用Server Actions成功后,再用useAppDispatch同步状态:

"use client";
import { useFormState } from "react-dom";
import { adminCreateProduct } from "@/app/actions";
import { useAppDispatch } from "@/app/store/hooks";
import { addProduct } from "@/app/store/slices/model/modelSlice"; // 同步添加产品的Action

export default function CreateProductForm() {
  const dispatch = useAppDispatch();
  const [state, formAction] = useFormState(adminCreateProduct, undefined);

  const handleSubmit = async (formData: FormData) => {
    const data = Object.fromEntries(formData) as createProduct;
    const newProduct = await formAction(data);
    if (newProduct) {
      // 成功后更新客户端Redux Store
      dispatch(addProduct(newProduct));
    }
  };

  return (
    <form action={handleSubmit}>
      {/* 表单字段 */}
      <input type="text" name="name" placeholder="产品名称" />
      <button type="submit">创建产品</button>
      {state?.error && <p className="text-red-500">{state.error}</p>}
    </form>
  );
}

内容的提问来源于stack exchange,提问作者chowacross

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:06:11