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

Remix Run向服务端发送数据及useActionData使用问题求助

Remix 提交POST请求问题解答

核心疑问明确

  • 路由模块导出的action函数就是编写POST等变更类请求逻辑的正确位置。它和处理GET请求的loader同属服务端执行逻辑,不会被打包到客户端代码中。
  • 你遇到createCart is not a function报错的根本原因:createCart是服务端执行的方法,你直接在客户端点击事件回调里调用,客户端作用域根本访问不到服务端定义的函数,自然会抛出不存在的错误。

点击按钮提交数据的正确实现

  1. 先把创建购物车的核心逻辑迁移到action函数中,从请求中解析参数、完成服务端调用后返回结果即可,参考代码:
// 该函数仅在服务端运行,不会暴露给浏览器
export async function action({ request }) {
  // 解析客户端提交的参数
  const formData = await request.formData();
  const goodsId = formData.get("id");
  const num = formData.get("amount");

  // 这里直接执行你的createCart逻辑,调用内部接口/操作数据库都可以
  const cartInfo = await createCart(goodsId, Number(num));

  // 返回执行结果,客户端可通过useActionData直接获取
  return { code: 0, data: cartInfo, msg: "创建成功" };
}
  1. 客户端触发提交可根据场景二选一:
    • 优先用Remix提供的Form组件,无需手写点击事件,点击提交按钮会自动向当前路由action发POST请求,代码最简洁:
    import { Form, useActionData } from "@remix-run/react";
    
    export default function GoodsPage() {
      // 获取action返回的结果,行为和useLoaderData一致,action执行后会自动同步更新
      const actionRes = useActionData<typeof action>();
      return (
        <div>
          <Form method="post">
            {/* 隐藏域传参,也可以是可见的表单项 */}
            <input type="hidden" name="id" value="当前商品id" />
            <input type="hidden" name="amount" value={1} />
            <button type="submit">加入购物车</button>
          </Form>
          {actionRes?.code === 0 && <span>加入购物车成功</span>}
        </div>
      )
    }
    
    • 如果需要先执行客户端校验、交互逻辑再提交,就用你已经引入的useSubmit钩子手动触发提交,不要直接调用服务端方法:
    import { useSubmit, useActionData } from "@remix-run/react";
    
    export default function GoodsPage() {
      const submit = useSubmit();
      const actionRes = useActionData<typeof action>();
    
      const handleClick = () => {
        // 这里可以写提交前的客户端逻辑,比如参数校验、埋点上报
        const submitData = {
          id: "当前商品id",
          amount: 1
        };
        // 调用submit提交数据,自动触发对应action执行
        submit(submitData, { method: "post" });
      };
    
      return (
        <div>
          <button onClick={handleClick}>加入购物车</button>
          {actionRes?.code === 0 && <span>加入购物车成功</span>}
        </div>
      )
    }
    

注意:不要把带密钥的接口调用、数据库操作这类逻辑写到客户端组件代码里,Remix会自动对loader/action和客户端代码做隔离打包,避免敏感信息泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 20:27:20