React - useActionState、useFormStatus与表单处理

参考文档:react@18.3.1官方文档

一些概念:
React 的 Canary 和 Experimental 频道是 React 团队用于发布和测试新功能的渠道。

useActionState

useActionState 是一个可以根据某个表单动作的结果更新 state 的 Hook。

const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);

参数

  • fn:当按钮被按下或者表单被提交时触发的函数。当函数被调用时,该函数会接收到表单的上一个 state(初始值为传入的 initialState 参数,否则为上一次执行完该函数的结果)作为函数的第一个参数,余下参数为普通表单动作接到的参数。
  • initialState :state 的初始值。任何可序列化的值都可接收。当 action 被调用一次后该参数会被忽略。
  • 可选的permalink :通常是一个布尔值或字符串,用于指示是否将当前的状态与 URL 进行关联。如果 permalink 为 true,useActionState 可能会将状态信息保存到 URL 中,允许用户在刷新页面或分享链接时保留当前的表单状态。

返回

  • state:当前的 state。第一次渲染期间,该值为传入的 initialState 参数值。在 action 被调用后该值会变为 action 的返回值。
  • formAction:通常是一个函数,用于处理表单的提交或其他动作。它封装了提交表单所需的逻辑,可以通过调用这个函数来触发与服务器的交互或状态更新。调用 formAction 后,useActionState 会根据 fn 的执行结果更新 state 和 isPending,从而反映最新的状态。
  • isPending:指示当前的操作(通常是表单提交或其他异步操作)是否正在进行中

用法
假设我们要实现这样一个功能:
在这里插入图片描述
点击Submit,如果First Name值为空,提示:Name is required,如果不为空,提示:User save来模拟表单提交。
如果使用useState来实现
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
如果使用useActionState来实现

"use client";import { useActionState } from "react";
import { saveUser } from "@/lib/actions";
export default function Home() {
  const [data, action, isPending] = useActionState(saveUser, undefined);

  return (
    <form style={{ display: "flex", flexDirection: "column" }} action={action}>
      <label htmlFor="firstName">First Name</label>
      <input id="firstName" name="firstName" />
      <button disabled={isPending} style={{ marginTop: ".5rem" }}>
        {" "}
        Submit
      </button>
      {data?.error && <span style={{ color: "red" }}>{data?.error}</span>}
      {data?.message && <span style={{ color: "green" }}>{data?.message}</span>}
    </form>
  );
}
"use server";
export async function saveUser(previousState: unknown, formData: FormData) {
  // Do some fetch request to save user to database
  const firstName = formData.get("firstName") as string;
  await wait(1000);
  // Do some fetch request to save user to database await wait(1000)
  if (firstName === "") {
    return { error: "Name is required" };
  }

  return { message: "User saved" };
}

function wait(duration: number) {
  return new Promise((res) => {
    setTimeout(res, duration);
  });
}

useActionState 返回一个包含以下值的数组:

  1. 该表单的 当前 state,初始值为提供的 初始 state,当表单被提交后则改为传入的 action 的返回值。
  2. 传入 <form> 标签的 action 属性的 新 action。
  3. 一个 pending state,可以在处理 action 的过程中使用它。

表单被提交后,传入的 action 函数会被执行。返回值将会作为该表单的新的 当前 state。

传入的 action 接受到的第一个参数将会变为该表单的 当前 state。当表单第一次被提交时将会传入提供的 初始 state,之后都将传入上一次调用 action 函数的返回值。余下参数与未使用 useActionState 前接受的参数别无二致。

注意
useActionState Hook 当前仅在 React Canary 与 experimental 渠道中可用。此外,需要一款完全支持 React 服务器组件 特性的框架才可以使用 useActionState 的所有特性。

在早期的 React Canary 版本中,这个 API 是 React DOM 的一部分,称为 useFormState

  • 在支持 React 服务器组件的框架中使用该功能时,useActionState 允许表单在服务器渲染阶段时获得部分交互性。当不使用服务器组件时,它的特性与本地 state 相同。

  • 与直接通过表单动作调用的函数不同,传入 useActionState 的函数被调用时,会多传入一个代表 state 的上一个值或初始值的参数作为该函数的第一个参数。

useFormStatus

useFormStatus 是一个提供上次表单提交状态信息的 Hook。

const { pending, data, method, action } = useFormStatus();

参数
useFormStatus 不接收任何参数
返回
useFormStatus 返回一个包含以下属性的 status 对象:

  • pending:布尔值。如果为 true,则表示父级<form>正在等待提交;否则为 false。
  • data:实现了 FormData interface 的对象,包含父级<form>正在提交的数据;如果没有进行提交或没有父级 <form>,它将为 null。
  • method:字符串,可以是 ‘get’ 或 ‘post’。表示父级 <form> 使用 GET 或 POST HTTP 方法 进行提交。默认情况下,<form> 将使用 GET 方法,并可以通过 method 属性指定。
  • action:一个传递给父级 <form> 的 action 属性的函数引用。如果没有父级 <form>,则该属性为 null。如果在 action 属性上提供了 URI 值,或者未指定 action 属性,status.action 将为 null。

用法

示例:使用从 useFormStatus 返回的状态信息中的 data 属性来显示用户正在提交的数据是什么。
UsernameForm.js:

import {useState, useMemo, useRef} from 'react';
import {useFormStatus} from 'react-dom';

export default function UsernameForm() {
  const {pending, data} = useFormStatus();

  return (
    <div>
      <h3>请求用户名:</h3>
      <input type="text" name="username" disabled={pending}/>
      <button type="submit" disabled={pending}>
        提交  
      </button>
      <br />
      <p>{data ? `请求 ${data?.get("username")}...`: ''}</p>
    </div>
  );
}

App.js

import UsernameForm from './UsernameForm';
import { submitForm } from "./actions.js";
import {useRef} from 'react';

export default function App() {
  const ref = useRef(null);
  return (
    <form ref={ref} action={async (formData) => {
      await submitForm(formData);
      ref.current.reset();
    }}>
      <UsernameForm />
    </form>
  );
}

actions.js

export async function submitForm(query) {
    await new Promise((res) => setTimeout(res, 2000));
}

在这里插入图片描述

注意

  • useFormStatus Hook 必须从在 内渲染的组件中调用。
  • useFormStatus 仅会返回父级 的状态信息。它不会返回同一组件或子组件中渲染的任何 的状态信息。

总结

useActionState钩子旨在无缝处理服务器操作。当您将服务器操作传递给 useActionState 时,它将返回一个包含错误(或状态)、isPending 状态和操作本身的对象。此设置对于管理表单提交和在返回结果之前跟踪加载状态特别有用。

useFormStatus钩子旨在让您深入了解表单的当前状态,例如了解表单是否处于 “submitting” 状态。这对于显示 UI 元素(如加载指示器)或阻止多个表单提交(直到当前提交完成)特别有用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/934010.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Oracle之表空间迁移

问题背景&#xff1a;一个数据表随着时间的累积&#xff0c;导致所在表空间占用很高&#xff0c;里面历史数据可以清除&#xff0c;保留近2个月数据即可 首先通过delete删除了2个月以前的数据。 按网上的教程进行空间压缩&#xff0c;以下sql在表所在用户执行: -- 允许表重新…

如何在UI自动化测试中创建稳定的定位器?

如何在UI自动化测试中创建稳定的定位器&#xff1f; 前言1. 避免使用绝对路径2. 避免在定位器中使用索引3. 避免多个类名的定位器4. 避免动态和自动生成的ID5. 确保定位器唯一6. 处理隐藏元素的策略7. 谨慎使用基于文本的定位器8. 使用AI创建稳定的定位器 总结 前言 在自动化测…

从一条慢sql优化,深入探讨mysql的优化器优化机制

在某环境发现一个前端请求报错&#xff0c;经查为一条复杂的sql耗时约70s&#xff0c;最终导致前端响应超时。下面叙述下本次问题排查及根因分析过程&#xff0c;供其他同学参考。 本文中使用到的数据库是mariadb&#xff0c;对于mysql也是基本适用。 一&#xff0c;连接算法…

SpringBoot+OSS文件(图片))上传

SpringBoot整合OSS实现文件上传 以前,文件上传到本地(服务器,磁盘),文件多,大,会影响服务器性能 如何解决? 使用文件服务器单独存储这些文件,例如商业版–>七牛云存储,阿里云OSS,腾讯云cos等等 也可以自己搭建文件服务器(FastDFS,minio) 0 过程中需要实名认证 … 1 开…

Linux其三,yum源配置,定时任务,免密登录和查找命令

目录 一、Linux的两种软件安装方式 1、Yum源配置 2、linux中软件安装的另一种方式 rpm 3、安装mysql8.0 二、对虚拟机进行克隆 1、先关机 2、最新的状态&#xff0c;整个快照 3、开始克隆 4、修改克隆的服务器的硬件设置 5、修改克隆机的IP地址&#xff08;因为跟第一…

linux环境GitLab服务部署安装及使用

一、GitLab介绍 GitLab是利用Ruby onRails一个开源的版本管理系统&#xff0c;实现一个自托管的Git项目仓库&#xff0c;可通过Web界面进行访问公开的或者私人项目。 二、GitLab安装 1、先安装相关依赖 yum -y install policycoreutils openssh-server openssh-clients postf…

/usr/local/go/bin/go: cannot execute binary file: Exec format error

现象&#xff1a;ubuntu中安装go软件环境&#xff0c;报上述错误 原因&#xff1a;系统与软件不适配 解决&#xff1a;查看本系统的版本 找到x86-64对应的go版本即可

技术 + 舞蹈,探秘 SpringBoot 硬核广场舞团

3 系统分析 3.1 系统可行性分析 3.1.1 经济可行性 由于本系统是作为毕业设计系统&#xff0c;且系统本身存在一些技术层面的缺陷&#xff0c;并不能直接用于商业用途&#xff0c;只想要通过该系统的开发提高自身学术水平&#xff0c;不需要特定服务器等额外花费。所有创造及工作…

MySQL Workbench基本使用

MySQL Workbench 是一款由 MySQL官方开发和提供的统一可视化工具&#xff0c;专为数据库管理员、开发者和数据架构师设计。它提供了数据建模、SQL 开发和数据库管理的全面功能&#xff0c;支持 Windows、Linux 和 macOS 操作系统。 MySQL Workbench 是一个强大的工具&#xff…

fedora下Jetbrains系列IDE窗口中文乱码解决方法

可以看到窗口右部分的中文内容为小方块。 进入 Settings - Appearance & Behavior - Appearance - Use custom font : Note Sans Mono CJK SC &#xff0c;设置后如下图&#xff1a;

厦门凯酷全科技有限公司抖音电商服务的卓越典范

在短视频和直播带货迅速崛起的时代&#xff0c;厦门凯酷全科技有限公司&#xff08;以下简称“凯酷全科技”&#xff09;以其专业的服务、创新的精神以及对市场的深刻理解&#xff0c;在抖音电商领域中脱颖而出&#xff0c;成为众多品牌商家信赖的选择。本文将深入探讨凯酷全科…

Android显示系统(05)- OpenGL ES - Shader绘制三角形(使用glsl文件)

Android显示系统&#xff08;02&#xff09;- OpenGL ES - 概述 Android显示系统&#xff08;03&#xff09;- OpenGL ES - GLSurfaceView的使用 Android显示系统&#xff08;04&#xff09;- OpenGL ES - Shader绘制三角形 Android显示系统&#xff08;05&#xff09;- OpenGL…

Ubuntu中配置交叉编译工具的三条命令的详细研究

关于该把下面的三条交叉编译配置语句加到哪里&#xff0c;详情见 https://blog.csdn.net/wenhao_ir/article/details/144326545 的第2点。 现在试解释下面三条交叉编译配置语句&#xff1a; export ARCHarm export CROSS_COMPILEarm-buildroot-linux-gnueabihf- export PATH$…

【环境搭建】WordPress本地部署搭建及历史版本插件安装(windows系统)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【环境搭建】WordPress本地部署搭建及历史版本插件安装&#xff08;windows系统&#xff09; WordPress搭建环境部署&#xff08;…

【开源免费】基于SpringBoot+Vue.JS大创管理系统(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 081 &#xff0c;文末自助获取源码 \color{red}{T081&#xff0c;文末自助获取源码} T081&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

47 基于单片机的书库环境监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DHT11湿度传感器检测湿度&#xff0c;DS18B20温度传感器检测温度&#xff0c; 采用滑动变阻器连接数模转换器模拟二氧化碳和氧气浓度检测&#xff0c;各项数值通过lc…

outlook软件配置邮箱提示“到邮件服务器的加密连接不可用”

outlook软件配置邮箱提示“到邮件服务器的加密连接不可用” 问题描述&#xff1a; outlook软件里邮箱提示“已断开”或配置邮箱时提示“到邮件服务器的加密连接不可用”。 解决方案&#xff1a; 一、更改注册表&#xff08;可先导出备份&#xff09; winr&#xff0c;输入re…

Jmeter进阶篇(30)深入探索 JMeter 监听器

前言 在性能测试领域里,Apache JMeter 是一款经典而强大的工具,而其中的监听器(Listeners)组件更是发挥着不可或缺的关键作用。 监听器就像敏锐的观察者,默默记录测试执行过程中的各种数据,作为系统性能分析的数据依据。 本文将带你全方位走进 JMeter 监听器的奇妙世界,…

微调 Llama 3.2:让 AI 更好地读取医学图像

您是否想知道人工智能模型如何学习理解医学图像&#xff1f;今天&#xff0c;我将带您完成一个令人兴奋的项目&#xff1a;微调 Meta 的 Llama 3.2 Vision 模型来分析放射线图像。如果您不是技术专家&#xff0c;也不要担心 - 我会用简单的术语来解释。 它是如何运作的&#x…

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验二----网络分析(超超超详细!!!)

相信实验一大家已经完成了&#xff0c;对Arcgis已进一步熟悉了&#xff0c;现在开启第二个实验 ArcMap实验--网络分析 目录 ArcMap实验--网络分析 1.1 网络分析介绍 1.2 实验内容及目的 1.2.1 实验内容 1.2.2 实验目的 2.2 实验方案 2.3 实验流程 2.3.1 实验准备 2.3.2 空间校正…