Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
React表单验证:结合Yup实现客户端校验与处理服务端提交错误_创想鸟

React表单验证:结合Yup实现客户端校验与处理服务端提交错误

react表单验证:结合yup实现客户端校验与处理服务端提交错误

本教程详细阐述了如何在React应用中结合react-hook-form和yup进行客户端表单验证,并重点解决了yup无法处理的服务器端提交错误。通过引入React的useState管理服务器响应的错误信息,并根据HTTP状态码或服务器返回数据动态显示错误提示,确保用户获得全面且准确的验证反馈。

1. 客户端表单验证与Yup

在React应用中,react-hook-form是一个流行的表单库,它提供了高性能、灵活且易于使用的表单管理能力。结合yup这个强大的JavaScript schema验证库,我们可以轻松实现复杂的客户端表单验证逻辑。

客户端验证的主要目的是在数据发送到服务器之前,对用户输入进行即时检查,例如验证字段是否为空、格式是否正确(如邮箱格式、密码长度等)。这能显著提升用户体验,减少不必要的服务器请求。

以下是一个使用yup定义验证schema的示例,它用于检查用户名和密码是否已填写:

import * as yup from "yup";// 定义验证 schemaconst schema = yup.object({  username: yup.string().required("用户名是必填字段"),  password: yup.string().required("密码是必填字段"), // 这里的“密码不正确”提示仅是针对必填的,并非业务逻辑}).required();

在React组件中,我们可以这样整合react-hook-form和yup:

import React, { useState } from "react";import { useForm } from "react-hook-form";import { yupResolver } from "@hookform/resolvers/yup";import * as yup from "yup";// ... (schema 定义同上)function Login() {  const {    handleSubmit,    register,    formState: { errors },  } = useForm({    resolver: yupResolver(schema), // 使用 yupResolver 链接 yup schema  });  const formSubmit = (data) => {    console.log("客户端验证通过的数据:", data);    // 这里将发送数据到服务器  };  return (          
{errors.username &&

{errors.username.message}

}
{errors.password &&

{errors.password.message}

}
);}

2. 服务器端验证的必要性与Yup的局限性

尽管yup在客户端验证方面表现出色,但它无法处理需要与后端数据库进行交互才能确定的验证逻辑。例如,yup可以检查密码是否为空,但它无法判断用户输入的密码是否与数据库中存储的某个账户的密码匹配。这种业务逻辑层面的验证必须在服务器端进行。

当用户尝试登录时,服务器需要验证用户名是否存在、密码是否正确。如果凭据不匹配,服务器会返回一个错误响应。yup无法捕获和显示这类服务器端返回的错误信息,因为它只关注前端定义的schema规则。

3. 处理服务器端提交错误

为了处理服务器端返回的提交错误(例如“用户名或密码不正确”),我们需要在React组件中引入额外的状态管理机制。核心思是使用React的useState钩子来存储服务器返回的错误信息,并在UI中进行展示。

3.1 步骤一:定义错误状态

在你的React组件中,创建一个新的状态变量来存储服务器端返回的错误信息。

import React, { useState } from "react";// ... 其他导入function Login() {  const [submissionError, setSubmissionError] = useState(""); // 用于存储服务器提交错误  // ... 其他状态和 hook

3.2 步骤二:修改表单提交逻辑

在formSubmit函数中,当fetch请求完成并收到服务器响应时,根据响应的状态和内容来设置submissionError。

这里有两种常见的策略:

策略一:解析服务器返回的JSON数据中的错误信息服务器通常会在错误响应中包含一个JSON对象,其中包含详细的错误消息。

  const formSubmit = (data) => {    setSubmissionError(""); // 每次提交前清除之前的错误信息    fetch("http://localhost:3001/login", {      method: "POST",      body: JSON.stringify({ username: data.username, password: data.password }),      headers: { "Content-Type": "application/json" },    })      .then((response) => {        if (response.status === 200) {          // 登录成功          // props.router.navigate("/"); // 导航到其他页面          // setIsLoggedIn(true); // 更新登录状态          console.log("登录成功");          return response.json(); // 如果成功也可能返回数据        } else {          // 登录失败,处理错误响应          return response.json().then((responseData) => {            // 假设服务器返回 { error: "用户名或密码不正确" }            setSubmissionError(responseData.error || "登录失败,请重试。");            throw new Error(responseData.error || "登录失败"); // 抛出错误以便后续catch捕获          });        }      })      .then((responseData) => {        // 处理成功响应数据        console.log("成功响应数据:", responseData);      })      .catch((error) => {        console.error("网络或解析错误:", error);        // 如果错误已经在then块中设置,这里可以不再设置        // 如果是网络错误,可以设置通用的错误信息        if (!submissionError) { // 避免覆盖更具体的服务器错误            setSubmissionError("网络连接错误,请稍后再试。");        }      });  };

策略二:根据HTTP状态码自定义错误信息如果服务器只返回状态码而没有详细的错误JSON,你可以根据状态码在前端自定义错误消息。

  const formSubmit = (data) => {    setSubmissionError(""); // 每次提交前清除之前的错误信息    fetch("http://localhost:3001/login", {      method: "POST",      body: JSON.stringify({ username: data.username, password: data.password }),      headers: { "Content-Type": "application/json" },    })      .then((response) => {        if (response.status === 200) {          // 登录成功          // ... 成功处理逻辑          console.log("登录成功");        } else {          // 根据不同的 HTTP 状态码设置不同的错误信息          if (response.status === 401) { // Unauthorized            setSubmissionError("用户名或密码不正确。");          } else if (response.status === 400) { // Bad Request            setSubmissionError("请求参数有误,请检查。");          } else if (response.status === 500) { // Internal Server Error            setSubmissionError("服务器内部错误,请稍后再试。");          } else {            setSubmissionError("登录失败,请重试。");          }        }      })      .catch((error) => {        console.error("Error:", error);        setSubmissionError("网络连接错误,请稍后再试。");      });  };

3.3 步骤三:在UI中显示错误

在你的JSX中,条件性地渲染submissionError状态。通常,这个错误会显示在表单的顶部,因为它是一个整体的提交错误,而不是针对某个特定字段的错误。

  return (    

登录

{submissionError &&

{submissionError}

} {/* 显示服务器错误 */} {/* ... 用户名和密码输入框 */}
{errors.username &&

{errors.username.message}

}
{errors.password &&

{errors.password.message}

}
);

4. 完整示例代码整合

将上述修改整合到原始的Login组件中,我们可以得到一个同时处理客户端和服务器端验证的完整示例。

import React, { useState } from "react";// import Input from "./Input"; // 假设 Input 组件是自定义的,这里简化为原生 inputimport { useForm } from "react-hook-form";import { yupResolver } from "@hookform/resolvers/yup";import * as yup from "yup";import { useLocation, useNavigate, useParams } from "react-router-dom";// import useAuth from "../Components/Zustand - Auth/authLogin"; // 假设存在认证 hook// 路由 HOC,如果不需要可以移除function withRouter(Component) {  function ComponentWithRouterProp(props) {    let location = useLocation();    let navigate = useNavigate();    let params = useParams();    return (          );  }  return ComponentWithRouterProp;}// Yup 验证 schemaconst schema = yup.object({  username: yup.string().required("用户名是必填字段"),  password: yup.string().required("密码是必填字段"), // 这里的必填提示与服务器端验证“密码不正确”不同}).required();function Login(props) {  // const { isLoggedIn, setIsLoggedIn } = useAuth(); // 假设有认证状态管理  const [submissionError, setSubmissionError] = useState(""); // 新增:服务器提交错误状态  const {    handleSubmit,    register,    formState: { errors },    setError, // react-hook-form 提供的设置字段错误的方法  } = useForm({    resolver: yupResolver(schema),  });  const formSubmit = (data) => {    setSubmissionError(""); // 每次提交前清除之前的服务器错误信息    fetch("http://localhost:3001/login", {      method: "POST",      body: JSON.stringify({ username: data.username, password: data.password }),      headers: { "Content-Type": "application/json" },    })      .then((response) => {        if (response.status === 200) {          // 登录成功          props.router.navigate("/"); // 导航到主页          // setIsLoggedIn(true); // 更新登录状态          console.log("登录成功");          return response.json(); // 解析可能的成功响应数据        } else {          // 登录失败,处理服务器错误          // 尝试解析服务器返回的 JSON 错误信息          return response.json().then((responseData) => {            const errorMessage = responseData.error || "用户名或密码不正确。";            setSubmissionError(errorMessage); // 设置服务器提交错误            // 如果需要将错误关联到特定字段,可以使用 setError            // setError("password", { type: "server", message: errorMessage });            throw new Error(errorMessage); // 抛出错误以便链式调用中断          }).catch(() => {            // 如果服务器返回的不是 JSON 或者解析失败            const genericErrorMessage = "登录失败,请检查您的凭据。";            setSubmissionError(genericErrorMessage);            throw new Error(genericErrorMessage);          });        }      })      .then((responseData) => {        console.log("登录成功响应数据:", responseData);      })      .catch((error) => {        console.error("登录请求发生错误:", error.message);        // 这里的 catch 主要捕获网络错误或上面抛出的错误        if (!submissionError) { // 避免覆盖更具体的服务器错误            setSubmissionError("网络连接错误,请稍后再试。");        }      });  };  return (    

登录

{submissionError &&

{submissionError}

} {/* 假设 Input 组件接受 register 和 errorMessage prop */}
{errors.username &&

{errors.username.message}

}
{errors.password &&

{errors.password.message}

}
);}export default withRouter(Login);

5. 注意事项与最佳实践

用户体验至上: 提供清晰、友好的错误提示。避免直接暴露后端错误堆或敏感信息。例如,对于登录失败,统一提示“用户名或密码不正确”比区分“用户名不存在”和“密码错误”更安全。错误清除机制: 在用户重新输入或再次提交表单时,应清除上次的服务器端错误信息,避免旧错误干扰新操作。在formSubmit开始时调用setSubmissionError(“”)是一个好习惯。加载状态管理: 在表单提交期间,可以禁用提交按钮并显示加载指示器,防止用户重复提交,提升用户体验。安全性: 永远不要相信客户端的验证。所有关键业务逻辑和数据完整性验证都必须在服务器端重新执行。错误位置: 对于整体性的提交错误(如“用户名或密码不正确”),将其显示在表单顶部是合理的。如果服务器错误与特定字段高度相关,react-hook-form的setError方法也可以将服务器错误消息关联到具体的表单字段。HTTP状态码语义化: 后端应使用恰当的HTTP状态码来表示不同类型的错误(例如,400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、500 Internal Server Error),这有助于前端更准确地处理错误。错误日志: 在catch块中记录错误对于调试和监控至关重要,但不要将敏感信息暴露给用户。

通过以上方法,你可以在React应用中有效地结合客户端yup验证和服务器端错误处理,为用户提供健壮且友好的表单体验。

以上就是React表单验证:结合Yup实现客户端校验与处理服务端提交错误的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1521571.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
怎么利用JavaScript进行前端代码部署流程?
上一篇 2025年12月20日 14:17:45
如何通过JavaScript的异步生成器处理流数据,以及它在Node.js中读取大文件时的应用原理是什么?
下一篇 2025年12月20日 14:17:57

相关推荐

  • Java 正则表达式:查找双引号内所有指定字符串的出现次数

    本文旨在解决在 Java 中使用正则表达式查找双引号内特定字符串(例如 “variant”)的所有出现次数的问题。我们将提供一个完整的解决方案,包括正则表达式的构建、代码示例以及详细的解释,帮助开发者准确高效地完成此类任务。 在 Java 中,使用正则表达式查找字符串中特定模…

    2026年9月21日
    000
  • 百度极速版如何开启数据同步_百度极速版数据同步的设置方法

    用同一百度账号登录百度极速版是开启数据同步的关键,进入【我的】→【设置】→开启【书签同步】,完成账号绑定后,书签和搜索记录即可在多设备间自动同步。 想在不同设备上无缝使用百度极速版,开启数据同步是关键。只要用同一个百度账号登录,你的书签、搜索记录等信息就能自动保持一致。操作本身不难,主要是找到正确的…

    2026年9月21日
    000
  • 《如龙 极》《极2》 PS5、XSX|S版12月8日发售 支持中文

    《如龙 极》《极2》 PS5、XSX|S版12月8日发售 支持中文《如龙 极》《极2》 PS5、XSX|S版12月8日发售 支持中文《如龙 极》《极2》 PS5、XSX|S版12月8日发售 支持中文《如龙 极》《极2》 PS5、XSX|S版12月8日发售 支持中文

    来源:官方 Nintendo Switch™ 2平台游戏《人中之龙 极2》(预计2025年11月13日发售)数字版已于今日9月24日正式开启预购。 同时,《人中之龙 极》与《人中之龙 极2》的PlayStation®5及Xbox Series X|S版本将于2025年12月8日推出。此次新版本将新增…

    2026年9月21日 用户投稿
    000
  • win10打开图片提示“没有注册类”怎么办_win10图片打开注册类错误解决方案

    首先重置照片应用并修复系统文件,再通过PowerShell重新注册应用包,最后调整默认应用关联以解决“没有注册类”错误。 如果您尝试在Windows 10中打开图片文件,但系统弹出“没有注册类”的错误提示,则可能是由于默认图片查看应用的注册信息丢失或损坏。以下是解决此问题的步骤: 本文运行环境:De…

    2026年9月21日
    200
  • Spring Boot异常处理:为何需要自定义异常而非仅依赖HTTP状态码

    在Spring Boot应用中,自定义异常提供了比单一HTTP状态码更丰富的错误上下文,能够更精确地传达问题根源。这种细粒度的异常处理不仅提升了代码的可读性和可维护性,也极大地改善了用户体验,使客户端能够基于具体错误类型做出智能响应,而非仅仅接收到一个模糊的状态码。 为什么需要自定义异常? 在构建r…

    2026年9月21日
    100
  • Java Random类如何生成随机数

    Random类位于java.util包,通过实例化生成伪随机数;无参构造以系统时间作种子,带参构造用固定种子可复现序列;提供nextInt()、nextDouble()等方法生成不同类型随机值;指定范围整数可用rand.nextInt(max-min)+min实现;多线程推荐ThreadLocalR…

    2026年9月21日
    200
  • 构建与调试PHP简易路由系统:从原理到实践

    本文将指导您如何从零开始构建一个基础的PHP路由系统,实现URL到控制器和方法的映射。我们将深入探讨$_SERVER[‘REQUEST_URI’]的解析、控制器文件的动态加载、方法调用以及如何通过.htaccess进行URL重写。同时,文章还将详细讲解常见的“未定义变量”错误…

    2026年9月21日
    200
  • Linux中如何安装Redis_Linux安装Redis服务的完整教程

    安装编译环境和依赖:Ubuntu/Debian用apt安装build-essential tcl wget,CentOS/RHEL用yum安装Development Tools和tcl wget。2. 下载Redis 7.2.4源码包并%ignore_a_1%,进入目录后执行make编译,可选mak…

    2026年9月21日
    000
  • 小红书从哪里看私信记录?私信记录如何清理?

    在小红书上与朋友或喜欢的博主互动时,私信是必不可少的沟通方式。不少新手用户常常困惑于如何查找过往的聊天内容。本文将为你详细说明查看私信记录的具体步骤,并分享几种实用的清理方法,帮助你轻松管理私信箱,让对话界面更清爽。 一、如何找到小红书的私信记录? 查看私信的操作非常直观,只需几个简单步骤即可完成。…

    2026年9月21日
    000
  • PHP框架中间件有什么用处_PHP框架中间件设计与实现

    PHP框架中间件是处理请求和响应的过滤器,用于实现身份验证、日志记录、CORS等通用逻辑,核心价值在于解耦和提升可维护性。通过定义中间件接口、具体中间件类及管道调度器可实现自定义中间件,如身份验证或CORS处理。在Laravel中可通过Kernel.php配置全局、分组或路由级中间件,执行顺序按注册…

    2026年9月21日
    100
  • Java中字符到数字转换:解决for循环提前返回的常见陷阱

    本文探讨java中`for`循环在字符到数字转换时,因`return`语句放置不当导致程序提前终止、无法完整处理字符串的问题。我们将分析这种常见陷阱,并提供修正方案,演示如何正确利用循环填充数组,并在循环结束后统一返回最终结果,确保每个字符都能被准确映射和组合。 引言:字符到数字的映射需求 在编程实…

    2026年9月21日
    100
  • win10登录界面不显示用户头像或名称怎么办_恢复登录界面完整显示的操作方法

    登录界面缺少头像或账户名时,先检查账户名一致性,修复头像缓存,重设头像,扫描系统文件,必要时创建新管理员账户验证问题。 如果您在启动Windows 10后,登录界面仅显示密码输入框而缺少用户头像或账户名称,则可能是由于系统设置、缓存异常或账户配置问题导致。以下是恢复登录界面完整显示的详细操作方法。 …

    2026年9月21日
    100
  • word怎么设置页边距_word文档页边距设置步骤

    首先打开Word文档,点击“布局”选项卡中的“页边距”按钮,可选择预设值或点击“自定义页边距”进行详细设置,输入上下左右边距及装订线数值,再通过“应用于”选择范围,最后点击“确定”完成设置。 在使用Word编辑文档时,设置合适的页边距能让内容排版更美观,也符合打印或提交要求。下面介绍如何在Word中…

    2026年9月21日
    000
  • win10平板模式下屏幕键盘不自动弹出怎么办_恢复屏幕键盘自动弹出的技巧

    1、检查平板电脑模式设置,确保登录和使用时均启用平板模式并重启;2、在设备→输入中开启“不处于平板模式且未连接键盘时显示触摸键盘”;3、通过注册表编辑器创建InitialKeyboardIndicators值为2(十六进制)以强制启用键盘指示器;4、手动显示触摸键盘按钮并测试各应用兼容性,排查特定软…

    2026年9月21日
    100
  • Linux如何设置目录的执行权限

    目录的执行权限是访问其内容的“钥匙”,使用chmod命令可通过符号或八进制模式设置,常见权限为755(所有者rwx,组和其他用户rx),递归设置时推荐结合find命令分别处理文件和目录,避免误加执行权限。 在Linux中,设置目录的执行权限( x )并非意味着你可以“运行”这个目录,而是赋予了你进入…

    2026年9月21日
    100
  • 纯白颜值、双模切换:“纯白小金刚”技嘉M27UP ICE显示器登场

    纯白颜值、双模切换:“纯白小金刚”技嘉M27UP ICE显示器登场纯白颜值、双模切换:“纯白小金刚”技嘉M27UP ICE显示器登场纯白颜值、双模切换:“纯白小金刚”技嘉M27UP ICE显示器登场纯白颜值、双模切换:“纯白小金刚”技嘉M27UP ICE显示器登场

    在电竞DIY领域深耕多年的技嘉,始终致力于满足玩家对高颜值与个性化外设的追求。为助力用户打造一体化的纯白主题电竞空间,品牌全新推出了专为此场景设计的M27UP ICE显示器。这款产品定位于两千元左右价位,凭借出众的纯白外观、卓越性能与超高性价比,被玩家们亲切称为“纯白小金刚”。如果你正想入手一台兼具…

    2026年9月21日 用户投稿
    000
  • Java多线程API调用中Future.get()返回null的解决方案

    本文旨在解决%ignore_a_1%api调用中`future.get()`方法返回`null`的常见问题。当使用`callable`和`executorservice`并发执行api请求并尝试获取结果时,如果流读取逻辑不当,可能导致获取到的数据为空。文章将详细解释问题根源,并提供使用`string…

    2026年9月21日
    100
  • 交管12123处理非本人车辆违章怎么办_交管12123处理非本人车辆违章攻略

    可通过“交管12123”APP处理非本人名下车辆的交通违法,但需先完成备案。备案方式有两种:一是扫码备案,由车主生成二维码后驾驶人扫描并提交信息;二是短信验证备案,输入车牌号、发动机号后六位,系统向车主手机发送验证码,输入后完成备案。备案成功后,进入APP【更多】→【违法处理】,选择已备案车辆,查看…

    2026年9月21日
    000
  • 升级后如何检查兼容性

    检查兼容性是升级后确保系统稳定的关键,需先确认硬件配置与驱动支持,再验证软件运行及业务流程正常,最后通过系统日志排查潜在错误,逐步排除风险。 系统或软件升级后,检查兼容性是确保各项功能正常运行的关键步骤。直接进入实际使用前,花时间验证兼容性可以避免数据丢失、服务中断等问题。 检查硬件和驱动支持 某些…

    2026年9月21日
    100
  • .com网站安全维护_保障.com网站稳定的措施

    答案:保障.com网站稳定需加强安全防护、定期备份、实时监控和应急准备。部署防火墙、更新系统、使用HTTPS、限制端口;制定自动备份并异地存储,定期恢复测试;利用监控工具检测可用性与异常流量,优化加载速度;建立应急流程,严格权限管理,定期演练。细节执行到位才能确保长期安全稳定运行。 确保.com网站…

    2026年9月21日
    200

发表回复

登录后才能评论
关注微信