React 第四十一节Router 中 useActionData 使用方法案例以及注意事项

一、useActionData前言

useActionData 是 React Router 提供的一个钩子函数,用于获取在路由的 action 函数中返回的数据 。它通常与表单提交(通过 <Form> 组件)配合使用,用于处理表单提交后的服务器响应数据(如错误信息、成功状态等)。

二、useActionData核心用途

处理表单提交结果 :获取表单提交后服务器返回的数据(例如验证错误、成功消息等)。 动态反馈用户 :根据 action 返回的数据更新 UI(如显示错误提示)。 简化数据流:无需手动管理状态,直接通过路由 action 获取数据。

三、useActionData基本流程

用户提交表单(通过 <Form> 组件)。 路由的 action 函数处理提交数据(例如发送到服务器)。 action 返回数据(如错误对象、成功状态)。 组件通过 useActionData() 获取该数据并渲染反馈。

四 useActionData示例:用户登录表单

4.1、 定义路由配置(使用 createBrowserRouter)

javascript 复制代码
// src/main.jsx
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import LoginPage, { loginAction } from "./LoginPage";

const router = createBrowserRouter([
  {
    path: "/login",
    element: <LoginPage />,
    action: loginAction, // 处理表单提交的 action 函数
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

4.2、 定义 Action 函数(处理表单提交)

javascript 复制代码
// src/LoginPage.jsx
export async function loginAction({ request }) {
  const formData = await request.formData();
  const email = formData.get("email");
  const password = formData.get("password");

  // 简单的前端验证
  if (!email.includes("@")) {
    return { error: "邮箱格式不正确" };
  }

  try {
    // 模拟发送登录请求到服务器
    const response = await fetch("/api/login", {
      method: "POST",
      body: JSON.stringify({ email, password }),
    });
    const result = await response.json();

    if (result.success) {
      // 登录成功,重定向到主页
      return redirect("/");
    } else {
      // 返回服务器错误
      return { error: result.message };
    }
  } catch (err) {
    // 网络错误处理
    return { error: "网络请求失败,请重试" };
  }
}

4.3、 在组件中使用 useActionData

javascript 复制代码
// src/LoginPage.jsx
import { Form, useActionData } from "react-router-dom";

export default function LoginPage() {
  const actionData = useActionData(); // 获取 action 返回的数据

  return (
    <div>
      <h1>用户登录</h1>
      <Form method="post">
        {/* 显示错误信息 */}
        {actionData?.error && (
          <div style={{ color: "red" }}>{actionData.error}</div>
        )}

        <input
          type="email"
          name="email"
          placeholder="邮箱"
          required
        />
        <input
          type="password"
          name="password"
          placeholder="密码"
          required
        />
        <button type="submit">登录</button>
      </Form>
    </div>
  );
}

五、参数与返回值

参数:无。

返回值 : 最近一次路由 action 函数返回的数据。 如果没有 提交过 action 或 action 未返回数据,则返回 undefined。

六、注意事项

6.1、必须与 组件配合使用

useActionData 依赖于 React Router 的 <Form> 触发的 action 提交。如果使用普通 <form> 或手动提交,数据将无法被捕获。

6.2、数据类型一致性

Action 函数可以返回任意类型的数据(对象、字符串等),但组件中需根据实际返回类型处理渲染逻辑。

6.3、作用范围

数据仅与当前路由的 action 关联。如果跳转到其他路由,useActionData 会重置。

6.5、异步处理

Action 函数可以是异步的(如示例中的 async/await),但需确保正确处理加载状态(可配合 useNavigation 显示加载提示)。

七、高级用法:配合 useNavigation 处理加载状态

javascript 复制代码
import { useActionData, useNavigation, Form } from "react-router-dom";

function LoginPage() {
  const actionData = useActionData();
  const navigation = useNavigation();

  // 表单正在提交时显示加载状态
  const isSubmitting = navigation.state === "submitting";

  return (
    <Form method="post">
      {/* 错误提示 */}
      {actionData?.error && <div className="error">{actionData.error}</div>}

      <input name="email" />
      <input name="password" type="password" />

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "登录中..." : "登录"}
      </button>
    </Form>
  );
}

八、与 useLoaderData 的区别

useActionData: 获取表单提交后的响应数据 表单提交(POST/PUT/DELETE)触发 useLoaderData: 获取路由初始化时的数据 页面加载或跳转(GET)触发

九、常见场景

9.1、表单验证错误

Action 中校验数据格式,返回错误信息,前端直接渲染。

9.2、API 错误处理

捕获网络请求异常,返回统一错误提示。

9.3、操作成功反馈

返回成功状态并在页面显示"操作成功"提示。

useActionData是 React Router 提供了一种声明式的方式处理表单提交与反馈,用于简化了数据流管理。

相关推荐
lpfasd1233 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Data analyse4565 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai5 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
环境栈笔记6 小时前
指纹浏览器 WebRTC 怎么设置?从 ICE 候选、代理出口到功能验证
前端·人工智能·后端·自动化
赵大仁6 小时前
官网性能优化实战:LCP 3.2s → 2.1s、CLS 0.107 → 0,以及被我推翻的 6 个判断
前端·性能优化·cls·lcp·core web vitals
xiancai_xianyu6 小时前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
小羊没烦恼!7 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
史瓦辛格7 小时前
给 DeepSeek Harness 写费用插件:把「这次会话花了多少钱」算准
前端·deepseek
星光不问赶路人7 小时前
Vue 3 + TypeScript 中 enum 的使用实践
前端·vue.js
鸥梨菌Honevid7 小时前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet