본문 바로가기
더이상 하지 않는 망한 프로젝트/프로젝트 개발 과정

[앱삼] 6. (frontend) Sign up 페이지 세팅 및 validation

by VictorMeredith 2023. 3. 6.

pages/Sign.jsx

- 유저의 정보를 입력받아 저장 할 component 내의 state를 하나 만든다.

- 각 배열의 [0]은 값, [1]은 값의 유효검증 성공과 실패여부이다.

//임시 State
    const [userInfo, setUserInfo] = useState({
        id: ['',false],
        ps: ['',false],
        email:['',false],
        name: ['',false],
        aors: ['None', true]
    })

 

pages/Sign.jsx

- onChange에 넣어서 매번 실행해줄 함수 하나를 구현한다. type과 현재 값을 받아서 validation을 통해 검증한 후 state를 업데이트 해준다. 여기서 immer를 쓸까 했는데 코드가 더 길어질거 뻔해서 그냥 얕은복사 두 번 했다.

- validation() 함수는 utils 폴더에 모듈화한다.

  // onChange에 넣어 validate 후 임시state를 업데이트하는 함수
    const setInfo = useCallback((type, nowVal)=>{ //type과 값을 받아 validation
        if(type !== 'email' && nowVal.length>15){ //이메일을 제외한 모든 글자는 15자까지 제한한다.
            return;
        }
        else{
            let tempInfo = {...userInfo}
            let tempInfo_type = [...userInfo[type]] //2depth의 불변성을 지켜주기 위해 얕은복사 두번 함
            tempInfo_type[0] = nowVal;
            if(validation(type, nowVal)){ //validation util함수를 불러와서 사용한다.
                tempInfo_type[1] = true;
            }
            else{
                tempInfo_type[1] = false;
            }
            tempInfo[type] = tempInfo_type;
            setUserInfo(tempInfo);
        }
    },[userInfo])

 

/utils/validation.js

- 각각의 타입으로 분기해서 적절한 정규식을 통해 검증하는 유틸함수이다.

const idValExp = /^[a-zA-Z0-9]{5,15}$/
const psValExp = /^(?=.*[!@#$%^&*()\-_=+{};:,<.>/?]).{5,15}$/
const emailExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
const nameExp = /^[a-zA-Z0-9가-힣]{3,15}$/

const validation = (type, value)=>{
    // validation 
    switch(type){
        case 'id':
            if(idValExp.test(value)){
                return true
            }
            else{
                return false
            }
        case 'ps':
            if(psValExp.test(value)){
                return true
            }
            else{
                return false
            }
        case 'name':
            if(nameExp.test(value)){
                return true
            }
            else{
                return false
            }
        case 'email':
            if(emailExp.test(value)){
                return true
            }
            else{
                return false
            }
        case 'aors':
            return true
        default :
            console.log('Error!')
    }
}

export {validation}

 

pages/Sign.jsx

- submit 버튼을 눌렀을 때 axios요청할 함수를 추가해준다. 당장은 콘솔만 찍었지만 바로로그인 기능도 추가해줄거다.

    const signUp = (e)=>{
        e.preventDefault();
        if(userInfo.id[1] && userInfo.ps[1] && userInfo.email[1] && userInfo.name[1] && userInfo.aors[1]){
            axios.post('/api/auth/signup', userInfo)
            .then((result)=>{console.log(result)})
        }
        else{
            alert('다 채워라')
        }
    }

 

pages/Sign.jsx

- 적절히 화면에 표시해준다.

    return (
        <form className="signWrap" onSubmit={(e)=>{signUp(e)}}>
            <div className="idWrap formWrap">
                <p>id : 5~15자 영문, 특수문자 제외</p>
                <input type="id" value={userInfo.id[0]} onChange={(e)=>{setInfo('id', e.target.value)}} />
                {userInfo.id[1] ? '가능' : '불가능'}
            </div>
            <div className="psWrap formWrap">
                <p>ps : 5~15자 아무문자, 특수문자1개이상 필요</p>
                <input type="password" value={userInfo.ps[0]} onChange={(e)=>{setInfo('ps', e.target.value)}} />
                {userInfo.ps[1] ? '가능' : '불가능'}
            </div>
            <div className="emailWrap formWrap">
                <p>email : 이메일형식</p>
                <input type="email" value={userInfo.email[0]} onChange={(e)=>{setInfo('email', e.target.value)}}/>
                {userInfo.email[1] ? '가능' : '불가능'}
            </div>
            <div className="nameWrap formWrap">
                <p>name : 3~15자 한글,영문,숫자만 허용</p>
                <input type="text" value={userInfo.name[0]} onChange={(e)=>{setInfo('name', e.target.value)}} />
                {userInfo.name[1] ? '가능' : '불가능'}
            </div>
            <div className="aorsWrap">
                <p>Apple or Samsung : 중립, 애플, 삼성 중 하나 선택</p>
                <select name="" id="" onChange={(e)=>{setInfo('aors', e.target.value)}}>
                    <option value="None">중립</option>
                    <option value="Apple">Apple</option>
                    <option value="Samsung">Samsung</option>
                </select>            
            </div>
                <button type="submit">submit</button>
        </form>
    )

 

결과

가능 불가능을 실시간으로 검증하고 모두 가능일 때만 submit의 함수가 작동한다.

- 이제 서버로 가서 하나하나 재검증을 통해 에러를 캐치하고 db에 저장하는 컨트롤러를 만들어보자

댓글