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 databaseconst 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 元素(如加载指示器)或阻止多个表单提交(直到当前提交完成)特别有用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决docker拉取镜像失败问题

下载镜像 [roottest-server-01 ~]# docker pull nginx Using default tag: latest Error response from daemon: Get "https://registry-1.docker.io/v2/": read tcp 192.168.40.180:37356->54.227.20.253:443: read: connection reset by peer报错&#xff1a;E…

java Random随机数

Randoms是什么 在Java中&#xff0c;Random类是用于生成伪随机数的工具。它位于java.util包中。以下是一些使用Random类生成不同类型的随机数的方法&#xff1a; 1 创建 Random 类的实例 2 生成一个随机的int值&#xff08;范围从Integer.MIN_VALUE到Integer.MAX_VALUE&#…

ollama-webui - Ollama的ChatGPT 风格的 Web 界面

更多AI开源软件&#xff1a; 发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI小众AI&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型。收录了AI搜索引擎&#xff0c;AI绘画工具、AI对话聊天、AI音频工具、AI图片工具、AI视频工具、AI内容检测、AI法律助手、…

【算法练习】852. 山脉数组的峰顶索引

题目链接&#xff1a;852. 山脉数组的峰顶索引 根据题目用复杂度用O(long n)的方法解决问题&#xff0c;我们可以想到用二分查找解决&#xff1a; class Solution { public:int peakIndexInMountainArray(vector<int>& arr) {int left0,rightarr.size()-1;while(left…

LLM - 多模态大模型的开源评估工具 VLMEvalKit 部署与测试 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/144353087 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 VLMEva…

MySQL | 尚硅谷 | 第12章_MySQL数据类型精讲

MySQL笔记&#xff1a;第12章_MySQL数据类型精讲 文章目录 MySQL笔记&#xff1a;第12章_MySQL数据类型精讲第12章_MySQL数据类型精讲 1. MySQL中的数据类型2. 整数类型2.1 类型介绍2.2 可选属性2.2.1 M2.2.2 UNSIGNED2.2.3 ZEROFILL 2.3 适用场景2.4 如何选择&#xff1f;演示…

后端报错: message: “For input string: \“\““

这个错误信息表明后端尝试将一个空字符串 "" 转换为某种数值类型&#xff08;如整数、长整型等&#xff09;&#xff0c;但转换失败了。在许多编程语言中&#xff0c;如果你试图解析一个非数字的字符串&#xff08;在这个情况下是一个空字符串&#xff09;为数值类型…

Java 文件IO

一、什么是文件IO 文件是一个广义的概念&#xff0c;操作系统将很多资源都抽象成文件&#xff0c;这篇文章讲解文件特指硬盘上的文件 在硬盘上存在很多文件和目录&#xff0c;它们以一种N叉树的结构存储 注意&#xff1a;文件夹也是一种文件&#xff0c;它是一种目录文件 二、…

Rnnoise和SpeexDsp两种降噪方式有什么区别?

在蒙以CourseMaker 7.0软件中&#xff0c;增加了两种降噪模式&#xff0c;一种是Rnnoise&#xff0c;一种是SpeexDsp&#xff0c;这两种降噪模式有什么区别呢&#xff1f; Rnnoise 基于神经网络。当噪声与 rnnoise 的模型训练的噪声匹配时&#xff0c;它的效果非常好。比如说&…

使用aspx,完成一个转发http的post请求功能的api接口,url中增加目标地址参数,传递自定义header参数

使用aspx&#xff0c;完成一个转发http的post请求功能的api接口&#xff0c;url中增加目标地址参数&#xff0c;传递自定义header参数 首先&#xff0c;简单实现一下&#xff0c;如何在ASPX页面中实现这个功能实现代码说明&#xff1a;注意事项&#xff1a; 然后进阶&#xff0…

搭建Discuz论坛

lnmp l&#xff1a;linux操作系统 n&#xff1a;nginx前端页面 m&#xff1a;mysql数据库&#xff0c;账号密码等等都是保存在这个数据库里面 p&#xff1a;php------nginx擅长处理的是静态页面&#xff0c;页面登录账户&#xff0c;需要请求到数据库&#xff0c;通过php把动态…

鸿蒙分享(四):弹窗简单封装

代码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 引用的harmony-utils地址&#xff1a;OpenHarmony三方库中心仓 引用的harmony-dialog地址&#xff1a;OpenHarmony三方库中心仓 引用的loading-dialog地址OpenHarmony三方库中心仓 import…

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

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

扫二维码进小程序的指定页面

草料二维码解码器 微信开发者工具 获取二维码解码的参数->是否登陆->跳转 options.q onLoad: function (options) {// console.log("options",options.q)if (options && options.q) {// 解码二维码携带的链接信息let qrUrl decodeURIComponent(optio…

Java期末考试——题库+浓缩关键知识点

文章分为两部分&#xff1a;知识点总结和题库练习。 每个部分都有相关的考点和题型&#xff0c;确保覆盖考试的主要内容和常见题目。 一篇文章助你拿下期末&#xff01;&#xff01; Java期末考试——题库浓缩关键知识点 一、Java基础知识总结 1. 面向对象的基本特征 Java …

IC验证工程师基础知识

SVA 断言大法&#xff1a; SystemVerilog断言&#xff08;Assertion&#xff09;是一种用于设计验证的语言扩展&#xff0c;它可以在仿真或形式验证过程中指定设计属性并检查其正确性。SystemVerilog断言提供了一种表达设计应满足的属性的方式&#xff0c;允许设计者执行断言、…

C++ constexpr vs const

笼统的讲 constexpr 主要用于编译时期&#xff0c;const用于运行时&#xff0c;但实际上两者都可以同时用于编译时期和运行时。 const const可以修饰全局变量&#xff0c;局部变量&#xff0c;函数参数&#xff0c;指针&#xff0c;引用&#xff0c;也可以修饰类成员函数&…

负载均衡最佳实践及自定义负载均衡器

文章目录 负载均衡最佳实践及自定义负载均衡器一、负载均衡概述二、轮询负载均衡器&#xff08;一&#xff09;理论介绍&#xff08;二&#xff09;Java 实现示例&#xff08;三&#xff09;关键步骤&#xff08;四&#xff09;流程图 三、随机负载均衡器&#xff08;一&#x…

每日速记10道MySQL面试题16

其他资料 每日速记10道java面试题01-CSDN博客 每日速记10道java面试题02-CSDN博客 每日速记10道java面试题03-CSDN博客 每日速记10道java面试题04-CSDN博客 每日速记10道java面试题05-CSDN博客 每日速记10道java面试题06-CSDN博客 每日速记10道java面试题07-CSDN博客 每…

MitelMiCollab 身份绕过导致任意文件读取漏洞复现(CVE-2024-41713)

0x01 产品描述: Mitel MiCollab 是一个企业协作平台,它将各种通信工具整合到一个应用程序中,提供语音和视频通话、消息传递、状态信息、音频会议、移动支持和团队协作功能。0x02 漏洞描述: Mitel MiCollab 的 NuPoint 统一消息 (NPM) 组件中存在身份验证绕过漏洞,由于输入…