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

AI 概述
在 React 中使用服务器操作提交表单时,你可能会遇到这样一个问题:如何在服务器操作执行后(不)重置表单。这取决于你在 React 之上使用的框架,表单可能会自动重置,也可能需要你手动重置。 在 React 中,表单的默认行为是在提交操作后自动重置。无论表单提交是否成功,都会发生这种情况。当你在 React 之上使用 Next...

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

在 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 database

  return { 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 database

  return { message: "Post created" };
};

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

const PostCreateForm = () => {
  const [actionState, action] = useActionState(createPost, {
    message: "",
  });

  return (
    <form action={action}>
      <label htmlFor="name">Name:</label>
      <input
        name="name"
        id="name"
        defaultValue={(actionState.payload?.get("name") || "") as string}
      />

      <label htmlFor="content">Content:</label>
      <textarea
        name="content"
        id="content"
        defaultValue={(actionState.payload?.get("content") || "") as string}
      />

      <button type="submit">Send</button>

      {actionState.message}
    </form>
  );
};

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

以上关于如何在React中服务器操作提交表单后(不)重置表单?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 如何在React中服务器操作提交表单后(不)重置表单?

发表回复