개키우는개발자 : )

React SNS 1-6. 회원가입 폼 만들기 본문

React/React SNS Project

React SNS 1-6. 회원가입 폼 만들기

DOGvelopers 2019. 5. 15. 10:05
반응형

signup.js 에 회원가입 폼을 만들겠습니다.

 

회원가입 폼의 기능엔 비밀번호와 비밀번호 체크의 검증 함수

체크박스를 체크 유무 검증 기능, 그리고 일반적으로 함수를 만드는 것과

Coustom Hook, Hook들과 일반 함수, 값을 조합해서 새로운 Hook을 만드는 법을 확인해보겠습니다.

 

일반 함수 방법

 

Coustom Hook 방법은 난이도가 있는 방법입니다. 그럴땐 일반적으로 사용하셔도 전혀 상관없습니다.

import React, {useState} from 'react';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
import { Form , Input , Checkbox , Button} from 'antd';

const Signup = () =>{
    const [id,setId] = useState('');
    const [nick,setNick] = useState('');
    const [password,setPassword] = useState('');
    const [passwordCheck,setPasswordCheck] = useState('');
    const [term,setTerm] = useState(false);
    const [passwordError,setPasswordError] = useState(false);
    const [termError,setTermError] = useState(false);

    const onSubmit = (e) => {
        e.preventDefault();
        /**검증 로직 만들기
         * 1. 비밀번호와 비밀번호 체크가 다를 경우를 검증한다
         * 2. 약관 동의를 확인한다.
         */
        if(password !== passwordCheck){
            return setPasswordError(true);
        }
        if(!term){
            return setTermError(true);
        }
        console.log({
            id,
            nick,
            password,
            passwordCheck,
            term
        });
    };

    // Coustom Hook 이전
    const onChangeId = (e) => {
        setId(e.target.value);
    };
    const onChangeNick = (e) => {
        setNick(e.target.value);
    };
    const onChangePassword = (e) => {
        setPassword(e.target.value);
    };
    const onChangePasswordChk = (e) => {
        //비밀번호를 입력할때마다 password 를 검증하는 함수
        setPasswordError(e.target.value !== password);
        setPasswordCheck(e.target.value);
    };
    const onChangeTerm = (e) => {
        //체크박스 초기화
        setTermError(false);
        setTerm(e.target.checked);
    }

    return (
        <>
        <Head>
            <title>NodeBird</title>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.css" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.js"></script>
        </Head>
        <AppLayout>
        <Form onSubmit={onSubmit} style={{padding:10}}>
            <div>
                <label htmlFor="user-id">아이디</label><br/>
                <Input name="user-id" value={id} required onChange={onChangeId} />
            </div>
            <div>
                <label htmlFor="user-nick">닉네임</label><br/>
                <Input name="user-nick" value={nick} required onChange={onChangeNick} />
            </div>
            <div>
                <label htmlFor="user-password">비밀번호</label><br/>
                <Input name="user-password" type="password" value={password} required onChange={onChangePassword} />
            </div>
            <div>
                <label htmlFor="user-password-check">비밀번호체크</label><br/>
                <Input name="user-password-check" type="password" value={passwordCheck} required onChange={onChangePasswordChk} />
                {passwordError && <div style={{color : 'red'}}>비밀번호가 일치하지 않습니다.</div>}
            </div>
            <div>
                <Checkbox name="user-term" value={term} onChange={onChangeTerm}>동의 합니까?</Checkbox>
                {termError && <div style={{color : 'red'}}>약관에 동의하셔야 합니다.</div>}
            </div>
            <div style={{marginTop:10}}>
                <Button type="primary" htmlType="submit" >가입하기</Button>
            </div>
        </Form>
        </AppLayout>
        </>
    );
};

export default Signup;

 

실행 

비밀번호가 서로 다를 경우
동의 체크를 하지 않았을 경우
가입하기 실행
실행 결과

 

기능들은 잘 작동하는걸 확인할 수 있습니다.

 

Coustom Hook 

id,Nick,Password 가 중복되는 방식이라 중복코드를 하나의 함수로 바꾼 방법입니다.

import React, {useState} from 'react';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
import { Form , Input , Checkbox , Button} from 'antd';

const Signup = () =>{
    const [passwordCheck,setPasswordCheck] = useState('');
    const [term,setTerm] = useState(false);
    const [passwordError,setPasswordError] = useState(false);
    const [termError,setTermError] = useState(false);

    const onSubmit = (e) => {
        e.preventDefault();
        /**검증 로직 만들기
         * 1. 비밀번호와 비밀번호 체크가 다를 경우를 검증한다
         * 2. 약관 동의를 확인한다.
         */
        if(password !== passwordCheck){
            return setPasswordError(true);
        }
        if(!term){
            return setTermError(true);
        }
        console.log({
            id,
            nick,
            password,
            passwordCheck,
            term
        });
    };

    // Coustom Hook 후
    
    const onChangePasswordChk = (e) => {
        //비밀번호를 입력할때마다 password 를 검증하는 함수
        setPasswordError(e.target.value !== password);
        setPasswordCheck(e.target.value);
    };
    const onChangeTerm = (e) => {
        //체크박스 초기화
        setTermError(false);
        setTerm(e.target.checked);
    };

    //반복되는 코드들을 Coustom Hook을 활용하여 줄여줄 수 있다.
    const useInput = (initValue = null) =>{
        const [value,setter] = useState(initValue);
        const handler = (e) => {
            setter(e.target.value);
        }
        return [value,handler];
    };

    const [id,onChangeId] = useInput('');
    const [nick,onChangeNick] = useInput('');
    const [password,onChangePassword] = useInput('');

    return (
        <>
        <Head>
            <title>NodeBird</title>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.css" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.js"></script>
        </Head>
        <AppLayout>
        <Form onSubmit={onSubmit} style={{padding:10}}>
            <div>
                <label htmlFor="user-id">아이디</label><br/>
                <Input name="user-id" value={id} required onChange={onChangeId} />
            </div>
            <div>
                <label htmlFor="user-nick">닉네임</label><br/>
                <Input name="user-nick" value={nick} required onChange={onChangeNick} />
            </div>
            <div>
                <label htmlFor="user-password">비밀번호</label><br/>
                <Input name="user-password" type="password" value={password} required onChange={onChangePassword} />
            </div>
            <div>
                <label htmlFor="user-password-check">비밀번호체크</label><br/>
                <Input name="user-password-check" type="password" value={passwordCheck} required onChange={onChangePasswordChk} />
                {passwordError && <div style={{color : 'red'}}>비밀번호가 일치하지 않습니다.</div>}
            </div>
            <div>
                <Checkbox name="user-term" value={term} onChange={onChangeTerm}>동의 합니까?</Checkbox>
                {termError && <div style={{color : 'red'}}>약관에 동의하셔야 합니다.</div>}
            </div>
            <div style={{marginTop:10}}>
                <Button type="primary" htmlType="submit" >가입하기</Button>
            </div>
        </Form>
        </AppLayout>
        </>
    );
};

export default Signup;

테스트 결과 잘 실행되므로 이미지 첨부는 하지 않겠습니다.

 

useCallback 처리 

 

useCallback 사용하는 이유 props로 넘겨주는 메서드 또는 함수들은 useCallback으로 감싸주어야 한다.

함수 컴포넌트의 state가 바뀔때마다 전체 재실행되면서 함수들이 새로 생성된다. 함수는 객체이기 때문에 새로생성되면

이전객체와 다른 객체가 되면서 리랜더링이 발생됩니다. 그렇기 때문에 useCallback 처리를 해줍니다.

 

import React, {useState, useCallback} from 'react';
import Head from 'next/head';
import AppLayout from '../components/AppLayout';
import { Form , Input , Checkbox , Button} from 'antd';

const Signup = () =>{
    const [passwordCheck,setPasswordCheck] = useState('');
    const [term,setTerm] = useState(false);
    const [passwordError,setPasswordError] = useState(false);
    const [termError,setTermError] = useState(false);

    const onSubmit = useCallback((e) => {
        e.preventDefault();
        /**검증 로직 만들기
         * 1. 비밀번호와 비밀번호 체크가 다를 경우를 검증한다
         * 2. 약관 동의를 확인한다.
         */
        if(password !== passwordCheck){
            return setPasswordError(true);
        }
        if(!term){
            return setTermError(true);
        }
        
        //useCallback 하면 state 들을 dependence 배열에 넣어줍니다.
        //그래야 dependence 가 바뀔때 이벤트 함수가 생성이됩니다.
    },[password,passwordCheck,term]);

    const onChangePasswordChk = useCallback((e) => {
        //비밀번호를 입력할때마다 password 를 검증하는 함수
        setPasswordError(e.target.value !== password);
        setPasswordCheck(e.target.value);
        //password state를 사용하기때문에 password를 넣어준다
    },[passwordCheck]);
    const onChangeTerm = useCallback((e) => {
        //체크박스 초기화
        setTermError(false);
        setTerm(e.target.checked);
        //state를 사용하지 않기때문에 빈값
    },[]);

    //반복되는 코드들을 Coustom Hook을 활용하여 줄여줄 수 있다.
    const useInput = (initValue = null) =>{
        const [value,setter] = useState(initValue);
        const handler = useCallback((e) => {
            setter(e.target.value);
        },[]);
        return [value,handler];
    };

    const [id,onChangeId] = useInput('');
    const [nick,onChangeNick] = useInput('');
    const [password,onChangePassword] = useInput('');

    return (
        <>
        <Head>
            <title>NodeBird</title>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.css" />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/antd/3.18.1/antd.js"></script>
        </Head>
        <AppLayout>
        <Form onSubmit={onSubmit} style={{padding:10}}>
            <div>
                <label htmlFor="user-id">아이디</label><br/>
                <Input name="user-id" value={id} required onChange={onChangeId} />
            </div>
            <div>
                <label htmlFor="user-nick">닉네임</label><br/>
                <Input name="user-nick" value={nick} required onChange={onChangeNick} />
            </div>
            <div>
                <label htmlFor="user-password">비밀번호</label><br/>
                <Input name="user-password" type="password" value={password} required onChange={onChangePassword} />
            </div>
            <div>
                <label htmlFor="user-password-check">비밀번호체크</label><br/>
                <Input name="user-password-check" type="password" value={passwordCheck} required onChange={onChangePasswordChk} />
                {passwordError && <div style={{color : 'red'}}>비밀번호가 일치하지 않습니다.</div>}
            </div>
            <div>
                <Checkbox name="user-term" value={term} onChange={onChangeTerm}>동의 합니까?</Checkbox>
                {termError && <div style={{color : 'red'}}>약관에 동의하셔야 합니다.</div>}
            </div>
            <div style={{marginTop:10}}>
                <Button type="primary" htmlType="submit" >가입하기</Button>
            </div>
        </Form>
        </AppLayout>
        </>
    );
};

export default Signup;

 

Keyword : #CoustomHook,#useCallback

 

출처 : https://www.youtube.com/channel/UCp-vBtwvBmDiGqjvLjChaJw

 

ZeroCho TV

조현영(zerocho)의 JS 프로그래밍 강좌 시간 나는대로 저녁 10시 방송합니다. 컨텐츠: 무료 언어 강좌, 유료 실무 강좌(인프런에 올라감), 오픈소스 기여 방송, 책 쓰는 방송, Vue.js 사이드 프로젝트, 제로초 블로그 업그레이드하기 -- 소개 -- Node.js 교과서...

www.youtube.com

 

반응형
Comments