-
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 } }) } }
'NODE.JS' 카테고리의 다른 글
Social Media 만들기 - 6) search 기능 만들기 (Header) (0) 2021.07.06 Social Media 만들기 - 5) logout 기능 만들기 (Header) (0) 2021.07.06 Social Media 만들기 - 3) Redux , RefreshToken (Login 기능 만들기) (0) 2021.07.05 Social Media 만들기 - 2) Authentification 기능 만들기 (0) 2021.06.16 아마존 E-commerce 클론 -33) 채팅 기능 만들기(socket io) (0) 2021.05.30