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
英文地址,請注明出處:http://en.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道非計分的試驗題…