ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Social Media 만들기 - 4) Register 기능 만들기
    NODE.JS 2021. 7. 6. 04:47

     

     

    이제 레지스터 페이지를 만들자. 

     

    /register로 갔는데,만약 auth token이 있다면(로그인 했다면)

     history를 이용해서  "/"로 이동하도록 한다. 

     

    형식은 login과 매우 비슷하며, 

    여기서 userName은 저장할 때 lower로 변경해주고, 띄어쓰기는 생략해준다. 

    import React, { useEffect, useState } from 'react'
    import { useDispatch, useSelector } from 'react-redux'
    import { useHistory , Link} from 'react-router-dom'
    
    const Register = () => {
        const {auth} = useSelector(state => state)
        const history = useHistory()
        const dispatch = useDispatch();
    
        useEffect(() => {
            if(auth.token) history.push("/")
        }, [auth.token, history])
    
     
        const initialState = {fullName:'',userName:'', email:'', password:'',cf_password:'', gender:'male'};
        const [userData, setuserData] = useState(initialState);
        const {fullName,userName, email, password,cf_password} = userData;
    
        const [typePass, setTypePass] = useState(false);
        const [typeCfPass, setTypeCfPass] = useState(false);
    
    
        const handleCangeInput= e=>{
            const { name, value} = e.target;
            setuserData({...userData, [name]:value});
         }
        
    
        const handleSubmit=e=>{
            e.preventDefault();
            dispatch(register(userData));
        }
        return (
            <div className="auth_page">
                <form onSubmit={handleSubmit}>
                    <h3 className="text-uppercase text-center mb-4">Social Media</h3>
                    <div className="form-group">
                        <label htmlFor="fullName">Full Name</label>
                        <input type="text" className="form-control" id="fullName"   onChange={handleCangeInput} value={fullName} name="fullName"/>
                        <small  className="form-text text-muted">We'll never share your FullName with anyone else.</small>
                    </div>
                    <div className="form-group">
                        <label htmlFor="userName">User Name</label>
                        <input type="text" className="form-control" id="userName"  onChange={handleCangeInput} value={userName.toLowerCase().replace(/ /g, '')} name="userName"/>
                        <small  className="form-text text-muted">We'll never share your UserName with anyone else.</small>
                    </div>
                    <div className="form-group">
                        <label htmlFor="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" onChange={handleCangeInput} value={email} name="email"/>
                        <small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
                    </div>
                    <div className="form-group">
                        <label htmlFor="exampleInputPassword1">Password</label>
                        <div className="pass">
                            <input type={typePass? "text" : "password"} className="form-control" id="exampleInputPassword1"  onChange={handleCangeInput} value={password} name="password"/>
                            <small onClick={()=>setTypePass(!typePass)}>
                                {typePass? 'Hide': 'Show'}
                            </small>
                        </div>
                    </div>
                    <div className="form-group">
                        <label htmlFor="cf_password">Confirm Password</label>
                        <div className="pass">
                            <input type={typeCfPass? "text" : "password"} className="form-control" id="cf_password"  onChange={handleCangeInput} value={cf_password} name="cf_password"/>
                            <small onClick={()=>setTypeCfPass(!typeCfPass)}>
                                {typeCfPass? 'Hide': 'Show'}
                            </small>
                        </div>
    
                    </div>
                    <div className="row justify-content-between mx-0 mb-1">
                        <label htmlFor="male">
                            Male: <input type="radio" id="male" name="gender" value="male" defaultChecked onChange={handleCangeInput}/>
                        </label>
                        <label htmlFor="famale">
                            Female: <input type="radio" id="female" name="gender" value="female"  onChange={handleCangeInput}/>
                        </label>
                        <label htmlFor="other">
                            Other: <input type="radio" id="other" name="gender" value="other"  onChange={handleCangeInput}/>
                        </label>
                    </div>
    
                    <button type="submit" className="btn btn-dark w-100" disabled={fullName && userName &&email&&password && cf_password? false: true}>Register</button>
    
                    <p className="my-2">
                        You already have an account? <Link to="/login" style={{color:"crimson"}}>Login Now</Link>
                    </p>
                </form>
            </div>
        )
    }
    
    export default Register

    먼저 입력 형식을 확인한는 valid.js 을 utils폴더에 작성해주자. 

    email 형식은 검색창에 regex email js라고 치면 나온다. 

    const valid = ({fullname, username, email, password, cf_password}) => {
        const err = {}
    
        if(!fullname) {
            err.fullname = "Please add your full name."
        }else if(fullname.length > 25){
            err.fullname = "Full name is up to 25 characters long."
        }
    
        if(!username) {
            err.username = "Please add your user name."
        }else if(username.replace(/ /g, '').length > 25){
            err.username = "User name is up to 25 characters long."
        }
    
        if(!email) {
            err.email = "Please add your email."
        }else if(!validateEmail(email)){
            err.email = "Email format is incorrect."
        }
    
        if(!password) {
            err.password = "Please add your password."
        }else if(password.length < 6){
            err.password = "Password must be at least 6 characters."
        }
    
        if(password !== cf_password) {
            err.cf_password = "Confirm password did not match."
        }
    
        return {
            errMsg: err,
            errLength: Object.keys(err).length
        }
    }
    
    
    
    function validateEmail(email) {
        // eslint-disable-next-line
        const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }
      
    export default valid

     

    register 로 돌아가서 valid를 사용해서 나타내보자. 

    import React, { useState, useEffect } from 'react'
    import { useSelector, useDispatch } from 'react-redux'
    import { useHistory, Link } from 'react-router-dom'
    import { register } from '../redux/actions/authActions'
    
    const Register = () => {
        const { auth, alert } = useSelector(state => state)
        const dispatch = useDispatch()
        const history = useHistory()
    
        const initialState = { 
            fullname: '', username: '', email: '', password: '', cf_password: '', gender: 'male'
        }
        const [userData, setUserData] = useState(initialState)
        const { fullname, username, email, password, cf_password } = userData
    
        const [typePass, setTypePass] = useState(false)
        const [typeCfPass, setTypeCfPass] = useState(false)
    
        useEffect(() => {
            if(auth.token) history.push("/")
        }, [auth.token, history])
    
        
        const handleChangeInput = e => {
            const { name, value } = e.target
            setUserData({...userData, [name]:value})
        }
    
        const handleSubmit = e => {
            e.preventDefault()
            dispatch(register(userData))
        }
    
        return (
            <div className="auth_page">
                <form onSubmit={handleSubmit}>
                    <h3 className="text-uppercase text-center mb-4">V-Network</h3>
    
                    <div className="form-group">
                        <label htmlFor="fullname">Full Name</label>
                        <input type="text" className="form-control" id="fullname" name="fullname"
                        onChange={handleChangeInput} value={fullname}
                        style={{background: `${alert.fullname ? '#fd2d6a14' : ''}`}} />
                        
                        <small className="form-text text-danger">
                            {alert.fullname ? alert.fullname : ''}
                        </small>
                    </div>
    
                    <div className="form-group">
                        <label htmlFor="username">User Name</label>
                        <input type="text" className="form-control" id="username" name="username"
                        onChange={handleChangeInput} value={username.toLowerCase().replace(/ /g, '')}
                        style={{background: `${alert.username ? '#fd2d6a14' : ''}`}} />
                        
                        <small className="form-text text-danger">
                            {alert.username ? alert.username : ''}
                        </small>
                    </div>
    
                    <div className="form-group">
                        <label htmlFor="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="exampleInputEmail1" name="email"
                        onChange={handleChangeInput} value={email}
                        style={{background: `${alert.email ? '#fd2d6a14' : ''}`}} />
                        
                        <small className="form-text text-danger">
                            {alert.email ? alert.email : ''}
                        </small>
                    </div>
    
                    <div className="form-group">
                        <label htmlFor="exampleInputPassword1">Password</label>
    
                        <div className="pass">
                            
                            <input type={ typePass ? "text" : "password" } 
                            className="form-control" id="exampleInputPassword1"
                            onChange={handleChangeInput} value={password} name="password"
                            style={{background: `${alert.password ? '#fd2d6a14' : ''}`}} />
    
                            <small onClick={() => setTypePass(!typePass)}>
                                {typePass ? 'Hide' : 'Show'}
                            </small>
                        </div>
    
                        <small className="form-text text-danger">
                            {alert.password ? alert.password : ''}
                        </small>
                    </div>
    
                    <div className="form-group">
                        <label htmlFor="cf_password">Confirm Password</label>
    
                        <div className="pass">
                            
                            <input type={ typeCfPass ? "text" : "password" } 
                            className="form-control" id="cf_password"
                            onChange={handleChangeInput} value={cf_password} name="cf_password"
                            style={{background: `${alert.cf_password ? '#fd2d6a14' : ''}`}} />
    
                            <small onClick={() => setTypeCfPass(!typeCfPass)}>
                                {typeCfPass ? 'Hide' : 'Show'}
                            </small>
                        </div>
    
                        <small className="form-text text-danger">
                            {alert.cf_password ? alert.cf_password : ''}
                        </small>
                    </div>
    
                    <div className="row justify-content-between mx-0 mb-1">
                        <label htmlFor="male">
                            Male: <input type="radio" id="male" name="gender"
                            value="male" defaultChecked onChange={handleChangeInput} />
                        </label>
    
                        <label htmlFor="female">
                            Female: <input type="radio" id="female" name="gender"
                            value="female" onChange={handleChangeInput} />
                        </label>
    
                        <label htmlFor="other">
                            Other: <input type="radio" id="other" name="gender"
                            value="other" onChange={handleChangeInput} />
                        </label>
                    </div>
                    
                    <button type="submit" className="btn btn-dark w-100">
                        Register
                    </button>
    
                    <p className="my-2">
                        Already have an account? <Link to="/" style={{color: "crimson"}}>Login Now</Link>
                    </p>
                </form>
            </div>
        )
    }
    
    export default Register

     

     

    이제 dispatch해주자. 

    auth Action에

    register action을 추가해준다. 

    export const register = (data) => async (dispatch)=>{
        const check = valid(data);
        if(check.errLength>0){
        return dispatch({
            type:GLOBALTYPES.ALERT,
            payload:check.errMsg
           })
        }
        try{
    
            dispatch({
                type:GLOBALTYPES.ALERT,
                payload:{loading:true}
            })
            const res = await postDataAPI('register', data)
            dispatch({
                type:GLOBALTYPES.AUTH, 
                payload:{
                    token:res.data.access_token, 
                    user:res.data.user
                }
            })
            
            localStorage.setItem("firstLogin", true);
            dispatch({ 
                type: GLOBALTYPES.ALERT, 
                payload: {
                    success: res.data.msg
                } 
            })
        }catch(err){
            dispatch({
                type:GLOBALTYPES.ALERT, 
                payload:{
                    error: err.response.data.msg
                }
            })
        }
    }

     

     

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.