IT_World
[React] Signin form validation check 적용 본문
내가 이해가는 선에서 가장 직관적인 방법을 찾아 유효성 검증을 적용해보았다.
구현하면서 Vue와 React의 데이터 바인딩 방식의 차이를 체감할 수 있었다.
React는 데이터 흐름이 단방향이기 때문에 값이 변경될 때마다 state값을 다시 set을 하는 코드가 들어갔다.
Vue같은 경우 2-way binding이었기 때문에 이런 부분을 신경쓸 필요가 없었다.
React의 State를 사용하여 Form의 Error 정보 관리
UserId Form에 change가 있을 때마다, 정규식을 통해 validation check를 한 후 결과를 userIdError State에 저장한다.
const [userId, setUserId] = useState("");
const [userIdError, setUserIdError] = useState(false);
const onChangeUserId = (e) => {
const userIdRegex = /^[A-Za-z0-9+]{5,}$/;
if ((!e.target.value || (userIdRegex.test(e.target.value)))) setUserIdError(false);
else setUserIdError(true);
setUserId(e.target.value);
};
Error 정보 State로 조건부 렌더링
논리 연산자로 If를 인라인으로 표현
조건부 렌더링을 구현할 수 있는 방법은 많았는데, 나는 아래 방법을 사용하였다.
{userIdError && <div>~</div>}
앞의 조건이 true일 경우, 뒤의 element가 렌더링 된다.
앞의 조건이 false일 경우, 뒤의 element는 렌더링 되지 않는다.
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={20} placeholder="UserID" value={userId} onChange={onChangeUserId} />
{userIdError && <div class="invalid-input">User ID must be at least 5 letter and contain letters or numbers.</div>}
</Col>
</Form.Group>
소스코드
import React, { useState } from 'react';
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Container from 'react-bootstrap/Container';
import { Link } from 'react-router-dom'
function Join() {
const [userId, setUserId] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [userName, setUserName] = useState("");
const [email, setEmail] = useState("");
const [userIdError, setUserIdError] = useState(false);
const [passwordError, setPasswordError] = useState(false);
const [confirmPasswordError, setConfirmPasswordError] = useState(false);
const [userNameError, setUserNameError] = useState(false);
const [emailError, setEmailError] = useState(false);
const onChangeUserId = (e) => {
const userIdRegex = /^[A-Za-z0-9+]{5,}$/;
if ((!e.target.value || (userIdRegex.test(e.target.value)))) setUserIdError(false);
else setUserIdError(true);
setUserId(e.target.value);
};
const onChangePassword = (e) => {
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/;
if ((!e.target.value || (passwordRegex.test(e.target.value)))) setPasswordError(false);
else setPasswordError(true);
if (!confirmPassword || e.target.value === confirmPassword) setConfirmPasswordError(false);
else setConfirmPasswordError(true);
setPassword(e.target.value);
};
const onChangeConfirmPassword = (e) => {
if (password === e.target.value) setConfirmPasswordError(false);
else setConfirmPasswordError(true);
setConfirmPassword(e.target.value);
};
const onChangeUserName = (e) => {
setUserNameError(false);
setUserName(e.target.value)
};
const onChangeEmail = (e) => {
const emailRegex = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;
if (!e.target.value || emailRegex.test(e.target.value)) setEmailError(false);
else setEmailError(true);
setEmail(e.target.value);
};
const validation = () => {
if(!userId) setUserIdError(true);
if(!password) setPasswordError(true);
if(!confirmPassword) setConfirmPasswordError(true);
if(!userName) setUserNameError(true);
if(!email) setEmailError(true);
if(userId && password && confirmPassword && userName && email) return true;
else return false;
}
const onSubmit = (e) => {
if(validation()) return;
// API Call
}
return (
<div>
<Container className="panel">
<Form>
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={20} placeholder="UserID" value={userId} onChange={onChangeUserId} />
{userIdError && <div class="invalid-input">User ID must be at least 5 letter and contain letters or numbers.</div>}
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={20} type="password" placeholder="Password" value={password} onChange={onChangePassword} />
{passwordError && <div class="invalid-input">Password must be at least 8 characters and contain at least one letter and one number. </div>}
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={20} type="password" placeholder="Confirm Password" value={confirmPassword} onChange={onChangeConfirmPassword} />
{confirmPasswordError && <div class="invalid-input">Those passwords didn't match.</div>}
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={20} placeholder="Username" value={userName} onChange={onChangeUserName} />
{userNameError && <div class="invalid-input">Required.</div>}
</Col>
</Form.Group>
<Form.Group as={Row} className="mb-3">
<Col sm>
<Form.Control maxLength={50} type="input" placeholder="Email Address" value={email} onChange={onChangeEmail} />
{emailError && <div class="invalid-input">Please enter valid email format.</div>}
</Col>
</Form.Group>
<br />
<div className="d-grid gap-1">
<Button variant="secondary" onClick={onSubmit}>
Sign Up
</Button>
</div>
</Form>
<br />
<span className="text">Have an account? <Link to="/login" className="link">Sign In</Link></span>
</Container>
</div>
);
}
export default Join
'Front-End > React' 카테고리의 다른 글
[React] React에 대해 정리 (0) | 2022.05.19 |
---|---|
[React] 함수형 컴포넌트 (0) | 2022.04.14 |
[React] Login / Password (0) | 2022.04.14 |
[React] Webhook (0) | 2022.04.12 |
[React] event system (0) | 2022.04.08 |
Comments