gpt4 book ai didi

reactjs - React Hooks 表单验证 OnBlur 会触发所有字段,而不仅仅是特定字段

转载 作者:行者123 更新时间:2023-12-04 15:40:48 25 4
gpt4 key购买 nike

我目前正在使用这个惊人的钩子(Hook),我几个月前在互联网上的某个地方找到了我找不到的文章,但基本上我遇到的问题是,当我有一个大表格时,我会跳到下一个字段如果我使用 onBlur 它会为每个字段运行验证,因此所有需要的字段都会自动变为红色并显示错误(因为它们中没有任何内容和我的错误 css)。

我想等到该字段至少被输入,然后在与该特定字段相关的验证之前离开。

基本上我想知道是否有办法以某种方式等到输入至少被选择一次。我唯一能想到的就是为表单中的每个输入设置一个单独的钩子(Hook),或者以某种方式将一个事件附加到每个字段 - 如果它至少被选中一次,则为真/假,但不知道如何获得实现的。

import { useState, useEffect } from "react";

const useFormValidation = (initialState, validate, authenticate) => {
const [values, setValues] = useState(initialState);
const [errors, setErrors] = useState({});
const [isSubmitting, setSubmitting] = useState(false);

useEffect(() => {
if (isSubmitting) {
const noErrors = Object.keys(errors).length === 0;
if (noErrors) {
authenticate();
setSubmitting(false);
} else {
setSubmitting(false);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [errors]);

const handleChange = (event) => {
setValues({
...values,
[event.target.name]: event.target.value
});
}



const handleChangeChecked = (event) => {
setValues({...values, [event.target.name] : event.target.checked });
}

//THIS IS THE FUNCTION I AM TALKING ABOUT
const handleBlur = () => {
const validationErrors = validate(values);
setErrors(validationErrors);
}

const handleSubmit = (event) => {
event.preventDefault();
const validationErrors = validate(values);
setErrors(validationErrors);
setSubmitting(true);
}

return {
handleSubmit,
handleChange,
handleChangeChecked,
handleBlur,
values,
errors,
isSubmitting
};
}

export default useFormValidation;

这是一个示例验证,它也是传递给 useFormValidation 函数的第二个字段。
const validateCareTeam = (values) => {
let errors = {};

// First Name Errors
if (!values.firstName) {
errors.firstName = "First name is required";
}

// Last Name Errors
if (!values.lastName) {
errors.lastName = "Last name is required";
}

// Email Error
if (values.email && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
errors.email = "Please enter a valid email address";
}

const phoneno = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/
// Phone Number Errors
if (!values.phone) {
errors.phoneNumber = "Phone number is required";
} else if (!values.phone.match(phoneno)) {
errors.phoneNumber = "Please enter a phone number with 10 digits. 1 not necessary"
}

return errors;
}

export default validateCareTeam;

所以基本上如果在名字之后使用标签,那么所有其他必填字段 - 姓氏和电话号码都会变成红色。

我宁愿在点击提交按钮之前不事件运行验证,但我被要求立即进行验证。

最佳答案

下面的实现没有经过测试,但应该给出它应该如何工作的想法,阅读代码中的注释

import {
useState,
useEffect
} from "react";

const useFormValidation = (initialState, validate, authenticate) => {
const [values, setValues] = useState(initialState);
const [errors, setErrors] = useState({});
const [touched, setTouched] = useState([]); // NEW: stores all touched field names
const [isSubmitting, setSubmitting] = useState(false);

useEffect(() => {
if (isSubmitting) {
const noErrors = Object.keys(errors).length === 0;
if (noErrors) {
// NEW: probably need to flush touched
// setTouched([])
authenticate();
setSubmitting(false);
} else {
setSubmitting(false);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [errors]);

const handleChange = (event) => {
setValues({
...values,
[event.target.name]: event.target.value
});
if (!touched.includes(event.target.name)) { // NEW
setTouched([
...touched,
event.target.name
])
}
}



const handleChangeChecked = (event) => {
setValues({ ...values,
[event.target.name]: event.target.checked
});
if (!touched.includes(event.target.name)) { // NEW: check if we touched this field, then add to touched array
setTouched([
...touched,
event.target.name
])
}
}

//THIS IS THE FUNCTION I AM TALKING ABOUT
const handleBlur = () => {
const validationErrors = validate(values);

const touchedErrors = Object.keys(validationErrors) // NEW
.filter(key => touched.includes(key)) // get all touched keys
.reduce((acc, key) => {
if (!acc[key]) {
acc[key] = validationErrors[key]
}
return acc
}, {})
setErrors(touchedErrors); // NEW: touchedErrors has errors that are touched
}

const handleSubmit = (event) => {
event.preventDefault();
const validationErrors = validate(values);
// NEW do the same
const touchedErrors = Object.keys(validationErrors) // NEW
.filter(key => touched.includes(key)) // get all touched keys
.reduce((acc, key) => {
if (!acc[key]) {
acc[key] = validationErrors[key]
}
return acc
}, {})
setErrors(touchedErrors); // NEW: touchedErrors has errors that are touched
setSubmitting(true);
}

return {
handleSubmit,
handleChange,
handleChangeChecked,
handleBlur,
values,
touched, // NEW: just extend API
errors,
isSubmitting
};
}

export default useFormValidation;

关于reactjs - React Hooks 表单验证 OnBlur 会触发所有字段,而不仅仅是特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57874943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com