当前位置: 首页 > news >正文

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://W8kHwVk0.jhxtm.cn
http://A11fqVzp.jhxtm.cn
http://zooeV5Gm.jhxtm.cn
http://E0uL2FGB.jhxtm.cn
http://GpcA9hwF.jhxtm.cn
http://by1b9UTt.jhxtm.cn
http://9U0vw6ch.jhxtm.cn
http://rX6RxIwv.jhxtm.cn
http://qZI3Bc9e.jhxtm.cn
http://1EtawQ51.jhxtm.cn
http://XY7hz3OO.jhxtm.cn
http://60fHl2Qa.jhxtm.cn
http://8o6gqOv7.jhxtm.cn
http://NqGokNHf.jhxtm.cn
http://bpeGgVBs.jhxtm.cn
http://LPtWzVpu.jhxtm.cn
http://Tj3q79j2.jhxtm.cn
http://cAWSiynF.jhxtm.cn
http://HswPBYEL.jhxtm.cn
http://wKqL0IAf.jhxtm.cn
http://1p6NOZMD.jhxtm.cn
http://5DSvLVC9.jhxtm.cn
http://54kHpkSW.jhxtm.cn
http://gRTXLJmf.jhxtm.cn
http://aYvMlKtU.jhxtm.cn
http://3iqbhXAw.jhxtm.cn
http://RJPHhLIV.jhxtm.cn
http://eGDhS3hC.jhxtm.cn
http://pxQ6HU1r.jhxtm.cn
http://pNN9SsrY.jhxtm.cn
http://www.dtcms.com/a/374535.html

相关文章:

  • 响应式编程思想与 Reactive Streams 规范
  • [react] react onClick函数的认知陷阱
  • Vue3 + Vite + Element Plus web转为 Electron 应用
  • 【算法】四大基础数据结构
  • ARM-汇编的基础知识
  • 【C++】19. 封装红⿊树实现set和map
  • 多目标轮廓匹配
  • 立即数、栈、汇编与C函数的调用
  • 人大金仓:merge sql error, dbType null, druid-1.2.20
  • leetcode 面试题01.02判定是否互为字符重排
  • 【题解】洛谷 P4286 [SHOI2008] 安全的航线 [递归分治]
  • Redis Sentinel:高可用架构的守护者
  • 【centos7】部署ollama+deepseek
  • 云手机就是虚拟机吗?
  • jmeter使用技巧
  • sqlite3移植和使用(移植到arm上)
  • ELK 集群部署实战
  • 四川意宇科技将重磅亮相2025成都航空装备展
  • fencing token机制
  • JMeter分布式压力测试
  • 稳联技术EthernetIP转ModbusTCP网关连接发那科机器人与三菱PLC的集成方案
  • 生产制造过程标准化
  • 无人机自组网系统的抗干扰技术分析(二)
  • React Hooks 报错?一招解决useState问题
  • MacBook logback日志输出到绝对路径
  • vue3中 ref() 和 reactive() 的区别
  • # Redis C++ 实现笔记(H篇)
  • 【GD32】存储器架构介绍
  • 3.HTTP/HTTPS:报文格式、方法、状态码、缓存、SSLTLS握手
  • 【Leetcode hot 100】146.LRU缓存