如何在React中服务器操作提交表单后(不)重置表单?

server/2024/11/26 2:11:38/

在 React 中使用服务器操作提交表单时,你可能会遇到这样一个问题:如何在服务器操作执行后(不)重置表单。这取决于你在 React 之上使用的框架,表单可能会自动重置,也可能需要你手动重置。

在 React 中,表单的默认行为是在提交操作后自动重置。无论表单提交是否成功,都会发生这种情况。当你在 React 之上使用 Next.js(因为你需要一个框架来使用服务器操作),这种默认行为并不会改变。

在本教程中,我将展示如何在服务器操作执行后保持表单状态不变。但这种情况仅适用于服务器操作失败时。如果服务器操作成功,表单应按常规方式重置。

大家也看到了,我将文章标题定为“如何在 React 中服务器操作提交表单后(不)重置表单”,是因为在早期的 React 版本中,默认行为与此相反。这时,你需要在服务器操作后手动重置表单。

如何在 React 中不重置表单

接下来我将从一个示例开始,在这个示例中,用户可以通过在 Next.js 中使用带有服务器操作的表单来创建帖子。当用户提交表单时,数据会被发送到服务器

import { createPost } from "../actions/create-post";const PostCreateForm = () => {return (<form action={createPost}><label htmlFor="name">Name:</label><input name="name" id="name" /><label htmlFor="content">Content:</label><textarea name="content" id="content" /><button type="submit">Send</button></form>);
};

该表单包含两个字段和一个提交按钮。当用户点击提交按钮时,会调用服务器操作,提取表单数据,并在数据库中创建一个帖子。如果表单提交成功,表单会自动重置:

"use server";export const createPost = async (formData: FormData) => {const data = {name: formData.get("name"),content: formData.get("content"),};if (!data.name || !data.content) {throw new Error("Please fill in all fields");}// TODO: create post in database
};

但是,如果表单提交失败,原因是验证错误或数据库错误,用户就不得不重新输入数据,这显然不是很好的用户体验。我们可以通过在服务器操作中抛出一个错误来演示这一点,如果处理不当,这个错误将会导致应用程序崩溃。

通常,我们会使用 React 的 useActionState Hook 来处理服务器错误,并向用户显示一条消息。但是,这(目前)并不能阻止表单被重置:

"use client";import { useActionState } from "react";
import { createPost } from "../actions/create-post";const PostCreateForm = () => {const [actionState, action] = useActionState(createPost, {message: "",});return (<form action={action}><label htmlFor="name">Name:</label><input name="name" id="name" /><label htmlFor="content">Content:</label><textarea name="content" id="content" /><button type="submit">Send</button>{actionState.message}</form>);
};

服务器端,我们通常会捕获错误并向客户端返回一条消息。这里我为了简化操作,将直接返回这条消息:

"use server";type ActionState = {message: string;
};export const createPost = async (_actionState: ActionState,formData: FormData
) => {const data = {name: formData.get("name"),content: formData.get("content"),};if (!data.name || !data.content) {// throw new Error("Please fill in all fields");return { message: "Please fill in all fields" };}// TODO: create post in databasereturn { message: "Post created" };
};

现在我们已经建立了基本设置。表单在服务器操作成功后会自动重置,如果服务器操作失败,则会显示错误消息。但在后者的情况下,表单数据会丢失。下面让我们通过防止表单在失败操作后重置来解决这个问题。

首先,如果表单提交失败,我们在服务器操作中返回表单数据:

"use server";type ActionState = {message: string;payload?: FormData;
};export const createPost = async (_actionState: ActionState,formData: FormData
) => {const data = {name: formData.get("name"),content: formData.get("content"),};if (!data.name || !data.content) {return {message: "Please fill in all fields",payload: formData,};}// TODO: create post in databasereturn { message: "Post created" };
};

然后我们利用操作状态返回的表单数据,在服务器操作失败时,通过有条件地设置表单元素的默认值,来保持表单状态不变。

const PostCreateForm = () => {const [actionState, action] = useActionState(createPost, {message: "",});return (<form action={action}><label htmlFor="name">Name:</label><inputname="name"id="name"defaultValue={(actionState.payload?.get("name") || "") as string}/><label htmlFor="content">Content:</label><textareaname="content"id="content"defaultValue={(actionState.payload?.get("content") || "") as string}/><button type="submit">Send</button>{actionState.message}</form>);
};

现在,在服务器操作失败后,表单数据将保持不变。用户可以更正表单数据并重新提交,而无需重新输入数据。在服务器操作成功时,表单将按常规方式重置。


http://www.ppmy.cn/server/144957.html

相关文章

神经网络(系统性学习二):单层神经网络(感知机)

此前篇章&#xff1a; 神经网络中常用的激活函数 神经网络&#xff08;系统性学习一&#xff09;&#xff1a;入门篇 单层神经网络&#xff08;又叫感知机&#xff09; 单层网络是最简单的全连接神经网络&#xff0c;它仅有输入层和输出层&#xff0c;没有隐藏层。即&#x…

Unity 设计模式-原型模式(Prototype Pattern)详解

原型模式 (Prototype Pattern) 原型模式 (Prototype Pattern) 是一种创建型设计模式&#xff0c;它允许通过复制现有的对象来创建新对象&#xff0c;而不是通过直接实例化类。这意味着你可以通过克隆原型对象来生成新的实例&#xff0c;而不必依赖类的构造函数。该模式的核心思…

输入三个整数x,y,z,请把这三个数由小到大输出。-多语言实现

目录 C 语言实现 Python 实现 Java 实现 Js 实现 题目&#xff1a;输入三个整数x,y,z&#xff0c;请把这三个数由小到大输出。 程序分析&#xff1a;我们想办法把最小的数放到x上&#xff0c;先将x与y进行比较&#xff0c;如果x>y则将x与y的值进行交换&#xff0c;然后…

废品买卖回收管理系统|Java|SSM|Vue| 前后端分离

【重要①】前后端源码万字文档部署文档 【重要②】正版源码有问题包售后 【包含内容】 【一】项目提供非常完整的源码注释 【二】相关技术栈文档 【三】源码讲解视频 【其它服务】 【一】可以提供远程部署安装&#xff0c;包扩环境 【…

HarmonyOS4+NEXT星河版入门与项目实战(19)------状态管理 @Prop@Link@Provide@Consume

文章目录 1、@Prop@Link@Provide@Consume装饰器图解2、案例演示1、模块划分2、模块封装1、任务统计模块2、列表管理模块3、主界面4、完整代码3、父组件是对象@Prop可以是对象属性1、案例改造2、完整代码4、@Provide@Consume案例1、案例改造2、完整代码3、总结1、@Prop@Link@Pro…

双因子认证:统一运维平台安全管理策略

01双因子认证概述 双因子认证&#xff08;Two-Factor Authentication&#xff0c;简称2FA&#xff09;是一种身份验证机制&#xff0c;它要求用户提供两种不同类型的证据来证明自己的身份。这通常包括用户所知道的&#xff08;如密码&#xff09;、用户所拥有的&#xff08;如…

LeetCode 第 425 场周赛 个人题解

Q1. 最小正和子数组 原题链接 Q1. 最小正和子数组 思路分析 签到题&#xff0c;暴力就行 时间复杂度&#xff1a;O(N^2) AC代码 class Solution:def minimumSumSubarray(self, nums: List[int], l: int, r: int) -> int:n len(nums)res -1acc list(accumulate(num…

logstash 解析数组格式json数据:split, json

1&#xff0c;需求说明 原始数据格式&#xff1a; 1条 &#xff08;2*2&#xff09;》4个指标数据 [{"app":"aa","url":"www.1.com","metrics":[{"name":"cpu","value":11},{"name&quo…