React From表单使用Formik和yup进行校验

一、Formik的使用

官方文档地址:https://formik.org/docs/tutorial#validation

  1. 首先安装依赖
yarn add  formik

2.导入并初始化

import { useFormik } from 'formik';
initialValues:初始化 输入框的密码和账号 
onSubmit:当点击提交按钮时,调用这个钩子,拿到输入框的vaule值

 3.打印一下formik看一下都有哪些钩子

 const formik = useFormik({initialValues: {mobile: '',code: ''},validate,onSubmit: values => {// 拿到输入框的值console.log(values);},});console.log(formik);

 

4.在form表单中绑定这些钩子会自动调用

5.formik里提供了校验规则,但是还是要自己手动写一下

6.进行校验结果控制

{formik.touched.mobile && formik.errors.mobile ? < div className='validate'>{formik.errors.mobile}</div> : null}

 完整使用

import React from 'react'
import NavBar from '../NavBar/NavBar'
import style from './Login.module.scss'
import Input from '../Input/input.js'
// 导入表单验证的formik
import { useFormik } from 'formik';
//导入校验验证规则yup
//import * as yup from 'yup';
const validate = values => {const error = {}if (!values.mobile) {error.mobile = '手机号不能为空'}if (!values.code) {error.code = '验证码不能为空'}return error
}
export default function Login() {const formik = useFormik({initialValues: {mobile: '',code: ''},validate,onSubmit: values => {// 拿到输入框的值console.log(values);},});console.log(formik);return (<div className={style.root}><NavBar>登录</NavBar><div className='content'><h3>短信登录</h3><form onSubmit={formik.handleSubmit}><div className='input-item'><Inputname='mobile'placeholder='请输入手机号'value={formik.values.mobile}onChange={formik.handleChange}onBlur={formik.handleBlur}/>{formik.touched.mobile && formik.errors.mobile ? < div className='validate'>{formik.errors.mobile}</div> : null}<div className='input-item'><Inputplaceholder='请输入验证码'extra='获取验证码'name='code'onChange={formik.handleChange}onBlur={formik.handleBlur}value={formik.values.code} />{formik.touched.code && formik.errorscode ? <div className='validate'>{formik.errors.code}</div> : null}</div><button type='submit' className='login-btn'>登录</button></div></form></div ></div >)
}

二、使用yup进行校验

第一部分的校验看起来不是很方便,但是如果使用yup进行校验的话会比较方便一些

yup文档:https://www.npmjs.com/package/yup

三、实战过程及讲解

工具职责
Formik表单状态管家(值、错误、是否通过)

Yup

校验规则书写器(字段必须满足什么条件)
useValldate自定义钩子,把错误信息转换为formik能用的格式
  1. 把validate函数注册给formik函数
<Formik validate={validate} ... />
validate(currentFormValues)   // 当前整个表单值
import { useCallback, useMemo } from 'react';
import { catchYupError } from '@tencent/dboss-module-utility/common/utils/yup/catchYupError';
import * as Yup from 'yup';
import { set } from 'lodash';
import { t } from '@i18n';
import { validationSchema as backupStorageValidationSchema } from '@tencent/dboss-module-dbs/components/BackupStorageConfigForm';
import { StepId } from '../constants';
import { CrossClusterRollbackFormValues } from '../types';const baseValidationSchemaMap = {sourceInstanceInfo: Yup.object({SourceInstanceId: Yup.string().required(t('该项为必填项')),StorageConfig: backupStorageValidationSchema({ allNotRequired: false }),}),// 其他步骤的校验逻辑
};export const useValidate = (stepId: StepId) => {const validationSchema = useMemo(() => {const schema = baseValidationSchemaMap[stepId];if (typeof schema === 'function') {return schema();}return schema;}, [stepId]);const formValidator = useCallback((formData: CrossClusterRollbackFormValues) => {const errors = {};if (validationSchema) {const schemaErrors = catchYupError(formData, validationSchema) ?? [];schemaErrors.forEach(({ path, message }) => {path && set(errors, path, message);});}switch (stepId) {case 'sourceInstanceInfo':// 移除这部分代码,因为 StorageConfig 的校验已经在 baseValidationSchemaMap 中处理了break;case 'rollbackBasicSettings':catchYupError(formData,Yup.object({PhysicalRollbackConfig: Yup.object({RollbackTime: Yup.string().required(t('该项为必填项')),}),}),).forEach(({ path, message }) => {path && set(errors, path, message);});break;case 'targetInstanceSettings':catchYupError(formData,Yup.object({InstanceName: Yup.string().required(t('该项为必填项')),}),).forEach(({ path, message }) => {path && set(errors, path, message);});break;case 'confirmation':break;}return errors;},[stepId, validationSchema],);return formValidator;
};

 

步骤规则(yup对象)
SourceInstanceInfoSourceInstanceInfo+StorageConfig
rollbackBasicSettingsPhysicalRollbackConfig.RollbackTime
targetInstanceSettingsInstanceName

4.执行yup校验(以sourceInstanceInfo为例子)

Yup.object({SourceInstanceId: Yup.string().required('该项为必填项'),StorageConfig: backupStorageValidationSchema({ allNotRequired: false }),
})

backupstoragevaldationSchema会生成:

Yup.object({BackupDir: Yup.string().required('该项为必填项'),Bucket: Yup.string().required('该项为必填项'),L5ServerName: Yup.string().required('该项为必填项'),Endpoint: Yup.string().required('该项为必填项'),AK: Yup.string().required('该项为必填项'),SK: Yup.string().required('该项为必填项'),
});

 5.catchYupError会将错误信息转换为数组

[{ path: 'SourceInstanceId', message: '该项为必填项' },{ path: 'StorageConfig.BackupDir', message: '该项为必填项' },{ path: 'StorageConfig.Bucket', message: '该项为必填项' },...
]

 6.组装成Formik可以用的errors对象

{SourceInstanceId: '该项为必填项',StorageConfig: {BackupDir: '该项为必填项',Bucket: '该项为必填项',...}
}

 7.formik收到errors

  • 如果 空对象 → 校验通过,立即执行 onSubmit
  • 如果 有字段 → 校验失败,阻断提交,并在对应 <InputField> 下显示红色提示

四、常见踩坑

  1. 字段路径写错
    例如把 StorageConfig.Bucket 写成 Bucket → Yup 找不到字段,永远通过。
  2. initialValues 缺字段
    缺 StorageType → Yup 认为它是 undefined,不会触发 required()
  3. allNotRequired: true 传错
    传了 true → Yup 内部  加 .required(),永远通过。
  4. catchYupError 返回空数组
    说明 Yup 侧已经通过,问题一定在 路径或初始值
一句话总结:
「Formik 负责喊『校验!』,Yup 负责喊『哪里错了!』,useValidate 负责把错误翻译成 Formik 能看懂的地图,地图为空就放行 onSubmit。」

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

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

相关文章

netty-scoket.io路径配置

1、服务端代码 package com.yh.service.socket;import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.store.RedissonStoreFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory…

20250910荣品RD-RK3588-MID开发板在Android13系统下解决点卡迪的屏闪屏的问题

20250910荣品RD-RK3588-MID开发板在Android13系统下解决点卡迪的屏闪屏的问题 2025/9/5 15:44缘起&#xff1a;荣品RD-RK3588-MID开发板在Android13系统下解决点卡迪的屏。 按 POWER按键 关机之后&#xff0c;2s之内再次短按 POWER按键&#xff0c;开机之后屏会抖动。 2s后短按…

正态分布 - 计算 Z-Score 的 无偏估计

正态分布 - 计算 Z-Score 的 无偏估计 flyfish Z-Score公式与计算步骤 1 公式&#xff08;样本Z-Score&#xff09; 实际应用中&#xff0c;我们几乎不知道“总体均值/标准差”&#xff0c;所以常用样本数据计算&#xff1a; zixi−xˉsz_i \frac{x_i - \bar{x}}{s}zi​sxi​−…

ai生成文章,流式传输(uniapp,微信小程序)

1.环境nutui-uniappvue3tsunocss2.功能源码包含ai生成逻辑&#xff0c;内容生成实时打字机功能&#xff0c;ai数据处理等<script setup lang"ts"> import {queryAIParams, } from /api/pagesA import { submitFn } from /api/aiimport Navbar from /component…

Linux设备内存不足如何处理

[rootlocalhost ~]# free -mtotal used free shared buff/cache available Mem: 31208 14317 1280 1551 15610 14657 Swap: 15927 2781 13146 [rootlocalhost ~]#从 free -m 输出来看&…

中间件八股

文章目录RedisRedis为什么快&#xff1f;Redis Redis为什么快&#xff1f; 首先它是内存数据库&#xff0c;所有数据直接操作内存而非磁盘&#xff0c;避免了 I/O 瓶颈&#xff1b;其次采用单线程模型&#xff0c;消除了多线程切换的开销&#xff0c;同时通过非阻塞 I/O 多路…

【参数详解与使用指南】PyTorch MNIST数据集加载

# 加载MNIST数据集 train_dataset datasets.MNIST(root./data, trainTrue, downloadTrue, transformtransform) # 下载训练集 test_dataset datasets.MNIST(root./data, trainFalse, downloadTrue, transformtransform) # 下载测试集在深度学习入门过程中&#xff0c;MNIST手…

闭包面试题

闭包&#xff08;Closure&#xff09; 是指一个函数能够记住并访问其词法作用域&#xff08;定义时的作用域&#xff09;&#xff0c;即使该函数在其词法作用域之外执行。一、通俗理解&#xff08;面试可这样开头&#xff09;&#xff1a;> 闭包就是一个函数“记住”了它出生…

WebSocket 双向通信实战:SCADA 移动端实时操控响应优化

引言&#xff1a;SCADA 移动端的 “延迟烦恼” 与破局之道在电力调度、水厂监控、智能制造等场景中&#xff0c;SCADA 系统&#xff08;数据采集与监视控制系统&#xff09;是当之无愧的 “工业指挥官”—— 它能实时采集设备运行数据&#xff08;如电网负荷、水泵压力、机床转…

SafeEar:浙大和清华联合推出的AI音频伪造检测框架,错误率低至2.02%

本文转载自&#xff1a;https://www.hello123.com/safeear ** 一、&#x1f512; SafeEar&#xff1a;你的声音 “防火墙”&#xff0c;让 AI 伪造音频无所遁形 担心自己的声音被 AI 模仿甚至伪造&#xff1f;SafeEar就是来帮你解决这个难题的&#xff01;它是由浙江大学和清…

uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南

在 uni-app 跨平台开发中&#xff0c;iOS 应用的日志与崩溃分析往往是开发者最头疼的问题。 日志分散&#xff1a;uni-app 的 JS 日志、原生插件日志、系统日志分布在不同位置&#xff1b;崩溃难复现&#xff1a;用户反馈的崩溃往往无法在开发机还原&#xff1b;符号化复杂&…

CSS定义网格的列模板grid-template-columns什么意思,为什么要用这么复杂的单词

这个词确实看起来复杂&#xff0c;但其实很好理解。让我来拆解一下&#xff1a;单词分解grid-template-columns grid - 网格template - 模板columns - 列连起来就是&#xff1a;网格模板列 → 定义网格的列模板为什么要用这么长的单词&#xff1f;语义明确&#xff1a;长单词能…

Umi-OCR:Windows7和Linux上可免费离线使用的OCR应用!

工具介绍 Umi-OCR 是一款免费、开源的离线OCR软件&#xff0c;主要由作者 hiroi-sora 用业余时间在开发和维护。 Umi-OCR 内置多国语言库&#xff0c;支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚以及二维码的扫描/生成。 适用平台&#xff1…

30 分钟让 AI 开口查订单:React-Native + Coze 全链路语音对话落地指南

一、前言&#xff1a;为什么你需要“可说话、能查库”的 AI&#xff1f; 聊天机器人在 2025 已不新鲜&#xff0c;但**“张嘴就能查询私有业务数据”**的端到端方案依然踩坑无数&#xff1a; ASR/TTS 选型多、SDK 难对齐大模型与内部 API 安全打通RN 端流式渲染 音频播放并发…

玄机--应急响应--webshell查杀

靶场连接1.黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx}使用命令查找特殊文件//搜索目录下适配当前应用的网页文件&#xff0c;查看内容是否有Webshell特征 find ./ type f -name "*.jsp" -exec grep -l "exec(" {} \; find ./ type f -name &…

Nodejs读取目录下面的文件

需求&#xff1a;给定一个目录&#xff0c;读取该目录下面的所有文件&#xff0c;包括该目录下面文件夹里面的子文件&#xff0c;子子文件......const fs require(fs);const path require(path);// 指定要遍历的目录const directoryPath D:\\;//调用函数入口处readDir(direc…

PPTist,一个完全免费的 AI 生成 PPT 在线网站

PPTist&#xff0c;一个完全免费的 AI 生成 PPT 在线网站 PPTist 是一个完全免费的 AI 生成 PPT 在线网站、PPT 在线演示网站、PPT 在线编辑网站。 它完全免费&#xff0c;无需登录注册&#xff0c;支持 AI 生成 PPT 功能&#xff0c;可以一句话生成 PPT &#xff0c;支持输入…

C++中操作重载与类型转换

文章目录基本概念调用选择作为成员还是非成员输入和输出运算符算术和关系运算符相等和不等运算符赋值运算符下标运算符递增和递减运算符成员访问运算符函数调用运算符lambda是函数对象标准库定义的函数对象可调用对象与function重载、类型转换与运算符类型转换运算符避免有二义…

Java学习之——“IO流“的进阶流之转换流的学习

在博主的上一篇博文中&#xff0c;详细的介绍了“IO”流中最基本的一些知识&#xff0c;包括基本的常见的字节流和字符流&#xff0c;以及对应的缓冲流&#xff0c;对于“IO”流基础知识相对薄弱的同学可以先去看博主的上一篇博文Java学习之——万字详解“IO流”中基本的字节流…

PMP考试结构、学习框架与基本术语

一、PMP考试整体结构 考试基本信息 考试形式&#xff1a;纸笔考试&#xff08;中国大陆地区&#xff09;考试时长&#xff1a;230分钟&#xff08;约4小时&#xff09;题目数量&#xff1a;180道题 170道单选题&#xff08;四选一&#xff09;10道多选题包含5道非计分的试验题…