IT_World

[React] Signin form validation check 적용 본문

Front-End/React

[React] Signin form validation check 적용

engine 2022. 4. 14. 14:52
 

내가 이해가는 선에서 가장 직관적인 방법을 찾아 유효성 검증을 적용해보았다. 

구현하면서 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