반응에 로그인이 있습니다.
import React, { Fragment, useState } from 'react';
import { useHistory } from "react-router-dom";
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import { auth } from '../actions';
export const Login = () => {
let history = useHistory();
const dispatch = useDispatch();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState({email: '', password: ''});
const validEmailRegex = RegExp(/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|.
(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i);
const handleChange = e => {
e.persist();
const { name, value } = e.target;
let validationError = error;
switch(name) {
case 'email':
setEmail(value);
validationError.email = validEmailRegex.test(value) ? '' : 'Email is not valid';
break;
case 'password':
setPassword(value)
validationError.password = value.length < 8 ? 'Password must be 8 characters
long!': '';
break;
case 'submit':
validationError.email = email.length < 1 ? 'Email is required' : '';
validationError.password = password.length < 1 ? 'Password is required' : '';
default:
break;
};
setError(validationError);
console.log('in change', error)
};
const validateForm = (errors) => {
let valid = true;
Object.values(errors).forEach(
// if we have an error string set valid to false
(val) => val.length > 0 && (valid = false)
);
return valid;
};
const validate = () => {
console.log('email,password', email, password);
let validationError = error;
if(!email){
validationError.email = 'Email is required';
}
if(!password){
validationError.password = 'Password is required';
}
setError(validationError);
console.log('in validate',error)
};
const onSubmit = e => {
e.preventDefault();
validate();
console.log('error on submit', error);
if(validateForm(error)) {
dispatch(auth(email, password, true));
history.replace('/home');
}else{
console.error('Invalid Form', error)
}
};
return (
<Fragment>
<div className="w-full max-w-sm container mt-20 mx-auto">
<form onSubmit={onSubmit}>
<div className="w-full mb-5">
<label className="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" htmlFor="email">
Email
</label>
<input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:text-gray-600" value={email} name='email' onChange={(e) => handleChange(e)} type="text" placeholder="Email" />
{ error && <span style={{color: "red"}}>{error['email']}</span>}
</div>
<div className="w-full mb-5">
<label className="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" htmlFor="password">
Password
</label>
<input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:text-gray-600" value={password} name='password' onChange={(e) => handleChange(e)} type="password" placeholder="Password" />
{ error && <span style={{color: "red"}}>{error['password']}</span>}
</div>
<div className="flex items-center justify-between">
<button className="mt-5 bg-green-400 w-full hover:bg-green-500 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
Login
</button>
</div>
<div className="text-center mt-4 text-gray-500"><Link to='/'>Cancel</Link></div>
</form>
</div>
</Fragment>
)
}
onchange에 필드 유효성 검사를 추가하고 제출하면 onchange 유효성 검사가 올바르게 작동하고 오류가 표시됩니다. 제출시 유효성 검사도 잘 작동하지만 필드를 변경하지 않고 제출하려고하면 구성 요소에 오류가 표시되지 않습니다.
나는 반응이 처음이며 이것이 올바른 방법인지 모르겠습니다. 미리 감사드립니다.
코드 샌드 박스에 코드를 넣었는데 제대로 작동하는 것 같습니다. className
속성을 제거 하고 redux
가져 오기 와 같은 문제를 테스트하는 데 필요하지 않은 항목을 주석 처리했습니다 .
className
속성을 제거했기 때문에 CSS
오류 span
가 실제로 렌더링되지만 표시되지 않는 문제 가 될 수 있습니다 (브라우저의 개발 도구를 확인하여 실제로 없는지 확인하십시오 span
).
또한 상태 처리 + 유효성 검사가 상당히 복잡해질 수 있고 많은 솔루션이 있기 때문에 많은 양식을 사용하는 경우 라이브러리를 사용하는 것이 좋습니다.
나는 내 자신의 라이브러리 ( 반응 유창한 형식)를 썼습니다 . 자유롭게 확인해보세요.
편집하다
여기서 문제는를 error
사용 하여 객체를 업데이트 할 때 setError
항상 동일한 객체 참조를 전달한다는 것입니다.
// this is not doing a copy
// validationError will have the same reference as error
let validationError = error;
// ...
// following line will not trigger a rerender
setError(validationError);
이후 error
와 validationError
같은 기준을 가지고, react
따라서 원인이됩니다, 변화가 일어나지있다 asume 것입니다 상태 업데이트의 구제 . 상태에서 복잡한 유형 (객체 또는 배열과 같은)으로 작업하는 경우 이전 참조를 조정하는 대신 항상 새 참조를 만들어야합니다.
// this is an actual copy using the spread operator
// validationError will have different reference than error
let validationError = {...error};
// ...
// triggers rerender as expected
setError(validationError);
2 편집
를 호출 할 때 validate
업데이트 된 validationError
개체 를 사용하기 위해에 대한 반환 값을 추가했습니다 validateForm
.
const validate = () => {
//..
let validationError = { ...error };
// ...
return validationError;
};
const onSubmit = e => {
// ...
const validationError = validate();
if (validateForm(validationError)) {
//...
}
};
업데이트 된 코드 샌드 박스를 참조하십시오 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다