#reactjs #use-state
#reactjs #состояние использования
Вопрос:
Я работаю над формой проверки на стороне клиента с помощью React, используя функцию компонента и useState. проблема в том, что когда я нажимаю «Отправить», handleSubmit обновляет состояния «проверки» с ошибками, но они не отображаются при изменении состояния. они отображаются только тогда, когда я ввожу некоторые значения в поля ввода. Как я мог это исправить?
ниже вы можете найти код:
import React, { useState } from 'react';
function RegistrationView() {
const [inputValues, setInputValue] = useState({
fName: '',
lName: '',
email: '',
password: '',
confirmPassword: '',
});
const [validation, setValidation] = useState({
fName: '',
lName: '',
email: '',
password: '',
confirmPassword: '',
});
//handle submit updates
function handleChange(event) {
const { name, value } = event.target;
setInputValue({ ...inputValues, [name]: value });
}
const handleSubmit = (e) => {
e.preventDefault();
let errors = validation;
//first Name validation
if (!inputValues.fName.trim()) {
errors.fName = 'First name is required';
} else {
errors.fName = '';
}
//last Name validation
if (!inputValues.lName.trim()) {
errors.lName = 'Last name is required';
} else {
errors.lName = '';
}
// email validation
const emailCond =
"/^[a-zA-Z0-9.!#$%amp;'* /=?^_`{|}~-] @[a-zA-Z0-9-] (?:.[a-zA-Z0-9-] )*$/";
if (!inputValues.email.trim()) {
errors.email = 'Email is required';
} else if (!inputValues.email.match(emailCond)) {
errors.email = 'Please ingress a valid email address';
} else {
errors.email = '';
}
//password validation
const cond1 = '/^(?=.*[a-z]).{6,20}$/';
const cond2 = '/^(?=.*[A-Z]).{6,20}$/';
const cond3 = '/^(?=.*[0-9]).{6,20}$/';
const password = inputValues.password;
if (!password) {
errors.password = 'password is required';
} else if (password.length < 6) {
errors.password = 'Password must be longer than 6 characters';
} else if (password.length >= 20) {
errors.password = 'Password must shorter than 20 characters';
} else if (!password.match(cond1)) {
errors.password = 'Password must contain at least one lowercase';
} else if (!password.match(cond2)) {
errors.password = 'Password must contain at least one capital letter';
} else if (!password.match(cond3)) {
errors.password = 'Password must contain at least a number';
} else {
errors.password = '';
}
//matchPassword validation
if (!inputValues.confirmPassword) {
errors.confirmPassword = 'Password confirmation is required';
} else if (inputValues.confirmPassword !== inputValues.Password) {
errors.confirmPassword = 'Password does not match confirmation password';
} else {
errors.password = '';
}
return setValidation(errors);
};
return (
<div>
<div className='sign-up-form'>
<form
id='registrationForm'
action='/'
method='POST'
onSubmit={handleSubmit}
>
<div className='form-control'>
<input
placeholder='First Name'
type='string'
name='fName'
id='fName'
className='input-field'
onChange={(e) => handleChange(e)}
value={inputValues.fName}
/>
{validation.fName amp;amp; <p>{validation.fName}</p>}
{validation.fName amp;amp; console.log(validation)}
</div>
<div className='form-control'>
<input
placeholder='Last Name'
type='string'
id='lName'
name='lName'
className='input-field'
onChange={(e) => handleChange(e)}
value={inputValues.lName}
/>
{validation.lName amp;amp; <p>{validation.lName}</p>}
</div>
<div className='form-control'>
<input
placeholder='email'
type='email'
name='email'
className='input-field'
onChange={(e) => handleChange(e)}
value={inputValues.email}
/>
</div>
{validation.email amp;amp; <p>{validation.email}</p>}
<div className='form-control'>
<input
placeholder='password'
type='password'
name='password'
className='input-field'
onChange={(e) => handleChange(e)}
value={inputValues.password}
required
/>
{validation.password amp;amp; <p>{validation.password}</p>}
</div>
<div className='form-control'>
<input
placeholder='confirm password'
type='password'
name='confirmPassword'
className='input-field'
onChange={(e) => handleChange(e)}
value={inputValues.confirmPassword}
required
/>
</div>
<button type='submit' id='submit-button'>
submit
</button>
<span className='form-input-login'>
Already have an account? Login <a href='#'>here</a>
</span>
</form>
</div>
</div>
);
}
export default RegistrationView;
Спасибо
Комментарии:
1. Правильно ли я вас понимаю, что вы хотите проверять во время ввода пользователем, а не после отправки? Если да, то поместите операторы if и setValidation из handleSubmit в handleChange.
Ответ №1:
Вы можете поместить логику проверки в отдельную функцию и вызывать ее при изменении TextInput с помощью useEffect
перехвата. Я надеюсь, что это поможет. Вы можете улучшить логику проверки любым удобным вам способом.
import React, { useEffect, useState } from "react";
function RegistrationView() {
const [inputValues, setInputValue] = useState({
fName: "",
lName: "",
email: "",
password: "",
confirmPassword: "",
});
const [validation, setValidation] = useState({
fName: "",
lName: "",
email: "",
password: "",
confirmPassword: "",
});
//handle submit updates
function handleChange(event) {
const { name, value } = event.target;
setInputValue({ ...inputValues, [name]: value });
}
const checkValidation = () => {
let errors = validation;
//first Name validation
if (!inputValues.fName.trim()) {
errors.fName = "First name is required";
} else {
errors.fName = "";
}
//last Name validation
if (!inputValues.lName.trim()) {
errors.lName = "Last name is required";
} else {
errors.lName = "";
}
// email validation
const emailCond =
"/^[a-zA-Z0-9.!#$%amp;'* /=?^_`{|}~-] @[a-zA-Z0-9-] (?:.[a-zA-Z0-9-] )*$/";
if (!inputValues.email.trim()) {
errors.email = "Email is required";
} else if (!inputValues.email.match(emailCond)) {
errors.email = "Please ingress a valid email address";
} else {
errors.email = "";
}
//password validation
const cond1 = "/^(?=.*[a-z]).{6,20}$/";
const cond2 = "/^(?=.*[A-Z]).{6,20}$/";
const cond3 = "/^(?=.*[0-9]).{6,20}$/";
const password = inputValues.password;
if (!password) {
errors.password = "password is required";
} else if (password.length < 6) {
errors.password = "Password must be longer than 6 characters";
} else if (password.length >= 20) {
errors.password = "Password must shorter than 20 characters";
} else if (!password.match(cond1)) {
errors.password = "Password must contain at least one lowercase";
} else if (!password.match(cond2)) {
errors.password = "Password must contain at least one capital letter";
} else if (!password.match(cond3)) {
errors.password = "Password must contain at least a number";
} else {
errors.password = "";
}
//matchPassword validation
if (!inputValues.confirmPassword) {
errors.confirmPassword = "Password confirmation is required";
} else if (inputValues.confirmPassword !== inputValues.Password) {
errors.confirmPassword = "Password does not match confirmation password";
} else {
errors.password = "";
}
setValidation(errors);
};
useEffect(() => {
checkValidation();
}, [inputValues]);
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div>
<div className="sign-up-form">
<form
id="registrationForm"
action="/"
method="POST"
onSubmit={handleSubmit}
>
<div className="form-control">
<input
placeholder="First Name"
type="string"
name="fName"
id="fName"
className="input-field"
onChange={(e) => handleChange(e)}
value={inputValues.fName}
/>
{validation.fName amp;amp; <p>{validation.fName}</p>}
{validation.fName amp;amp; console.log(validation)}
</div>
<div className="form-control">
<input
placeholder="Last Name"
type="string"
id="lName"
name="lName"
className="input-field"
onChange={(e) => handleChange(e)}
value={inputValues.lName}
/>
{validation.lName amp;amp; <p>{validation.lName}</p>}
</div>
<div className="form-control">
<input
placeholder="email"
type="email"
name="email"
className="input-field"
onChange={(e) => handleChange(e)}
value={inputValues.email}
/>
</div>
{validation.email amp;amp; <p>{validation.email}</p>}
<div className="form-control">
<input
placeholder="password"
type="password"
name="password"
className="input-field"
onChange={(e) => handleChange(e)}
value={inputValues.password}
required
/>
{validation.password amp;amp; <p>{validation.password}</p>}
</div>
<div className="form-control">
<input
placeholder="confirm password"
type="password"
name="confirmPassword"
className="input-field"
onChange={(e) => handleChange(e)}
value={inputValues.confirmPassword}
required
/>
</div>
<button type="submit" id="submit-button">
submit
</button>
<span className="form-input-login">
Already have an account? Login <a href="#">here</a>
</span>
</form>
</div>
</div>
);
}
export default RegistrationView;
Комментарии:
1. спасибо, я посмотрю на это!
Ответ №2:
Как указано в вашем коде, ошибки устанавливают базу проверки при вызове по ссылке, поэтому после установленного состояния компонент не отображается. Пожалуйста, попробуйте глубоко клонировать вашу ошибку, как показано ниже.
let errors = JSON.parse(JSON.stringify(validation));
Я надеюсь, что это сработает для вас. Спасибо
Комментарии:
1. Спасибо! это работает!
Ответ №3:
Вы можете попробовать клонировать с помощью отдельного оператора.
let errors = {...validation}
Или вы можете использовать библиотеку react-hook-form. Он прост в использовании и очень изолирован.
Комментарии:
1. Потрясающе! это работает! Спасибо! Могу ли я спросить вас, почему это работает таким образом??
2. В javascript объект и функции имеют непримитивный тип. это означает, что если вы назначаете объект другой переменной, в памяти обе переменные указывают на одну и ту же переменную. С помощью отдельного оператора (…) вы можете клонировать содержимое объекта вместо ссылки. вы можете посмотреть эту статью: edureka.co/blog/data-types-in-javascript