-
MERN 기본파일 만들기 - 13)Register Page 만들기NODE.JS 2021. 5. 13. 15:14
Login페이지와 마찬가지로
회원을 등록하는 페이지도 만들 것이다.
App.js
import React from 'react'; import {Route, Switch} from "react-router-dom"; import About from "./about"//index.js가 기본이기 때문에 굳이 타이핑하지 않아도 된다. import Login from "./RegisterLogin"; import Register from "./RegisterLogin/register"; function App() { return ( <div > <Switch> {/* <Route path="/" component={Home} /> */} <Route path = "/about" component={About}/> <Route path = "/login" component={Login}/> <Route path = "/register" component={Register}/> </Switch> </div> ); } export default App;
src>components>RegisterLogin>register.js
index.js에서와 비슷하게 lastname, name, email, password, password Comfirmation파트를 만들어준다.
isFormValid에 모든 폼이 다 작성해야만 다음으로 넘어가고, 비밀번호가 잘 작성되었는지 확인하는 파트를 넣어준다.
passwordValid는 비밀번호가 6자 이상인지 확인하고 비밀번호와 비밀번호 확인이 일치하는지 확인한다.
isFormEmpty는 비어있는 칸이 하나라도 있는지 확인한다.
import React, { Component } from 'react' import {connect} from 'react-redux'; import {registerUser} from '../../actions/user_actions'; class Register extends Component { state = { lastname: "", name:"", email:"", password: "", passwordConfirmation:"", errors:[] }; handleChange = event =>{ this.setState({[event.target.name]: event.target.value}) } displayErrors = errors=>{ errors.map((error, i)=><p key={i}>{error}</p>) } isFormValid = () =>{ let errors = []; let error; if(this.isFormEmpty(this.state)){ error = {message : "Fill in all fields"}; this.setState({errors: errors.concat(error)}); }else if(!this.isPasswordValid(this.state)){ error = {message:"Password is invalid"}; this.setState({errors:errors.concat(error)}); }else{ return true; } } isPasswordValid= ({password, passwordConfirmation})=>{ if(password.length <6||passwordConfirmation.length<6){ return false; } else if(passwordConfirmation!==password){ return false; }else{ return true; } } isFormEmpty= ({lastname, name, email, password, passwordConfirmation})=>{ return ( !name.length || !lastname.length|| !email.length|| !password.length|| !passwordConfirmation.length ); } submitForm = event=>{ event.preventDefault(); let dataToSubmit = { email : this.state.email, name : this.state.name, lastname:this.state.lastname, password : this.state.password, passwordConfirmation: this.state.passwordConfirmation } if(this.isFormValid()){ this.setState({errors:[]}); this.props.disptch(registerUser(dataToSubmit)) .then(response =>{ if(response.payload.success){ this.props.history.push('/login') }else{ this.setState({ errors:this.state.errors.concat("your attempt to send data to DB was failed") }) } }) .catch(err =>{ this.setState({ errors: this.state.errors.concat(err) }) }) }else{ console.error("Form is not valid"); } } render() { return ( <div className="container"> <div className="row"> <h2>Sign Up</h2> {/* 전체 사이즈 사용하려면 12사용한다. */} <form className="col s12" onSubmit={event =>this.submitForm(event)}> <div className="row"> <div className="input-field col s12"> <input name="lastname" value={this.state.lastname} onChange={e=> this.handleChange(e)} id="lastname" type = "text" className="validate" /> <label htmlFor = "email">lastname</label> <span className="helper-text" data-eroor="Type a right type lastname" data-success="right" /> </div> </div> <div className="row"> <div className="input-field col s12"> <input name="name" value={this.state.name} onChange={e=> this.handleChange(e) } id="name" type = "name" className="validate" /> <label htmlFor = "name">name</label> <span className="helper-text" data-eroor="wrong" data-success="right" /> </div> </div> <div className="row"> <div className="input-field col s12"> <input name="email" value={this.state.email} onChange={e=> this.handleChange(e) } id="email" type = "email" className="validate" /> <label className = "active" for = "email">email</label> <span className="helper-text" data-eroor="wrong" data-success="right" /> </div> </div> <div className="row"> <div className="input-field col s12"> <input name="password" value={this.state.password} onChange={e=> this.handleChange(e) } id="password" type = "password" className="validate" /> <label className = "active" for = "password">password</label> <span className="helper-text" data-eroor="wrong" data-success="right" /> </div> </div> <div className="row"> <div className="input-field col s12"> <input name="passwordConfirmation" value={this.state.passwordConfirmation} onChange={e=> this.handleChange(e) } id="passwordConfirmation" type = "password" className="validate" /> <label className = "active" for = "passwordConfirmation">password Confirmation</label> <span className="helper-text" data-eroor="wrong" data-success="right" /> </div> </div> {this.state.errors.length>0 && ( <div> {this.displayErrors(this.state.errors)} </div> )} <div className="row"> <div className="col s12"> <button className="btn waves-effect red lighten-2" type="submit" name = "action" onClick={this.submitForm} >Create an account </button> </div> </div> </form> </div> </div> ) } } export default connect(mapStateToProps)(Register);
src>actions>user_actions.js
import axios from 'axios'; import { LOGIN_USER, REGISTER_USER } from './types'; export function loginUser(dataToSubmit){ const request = axios.post('api/users/login', dataToSubmit) .then(response => response.data) return { type:LOGIN_USER, payload: request } }; export function registerUser(dataToSubmit){ const request = axios.post('api/users/register', dataToSubmit) .then(response => response.data) return { type:REGISTER_USER, payload: request } };
src>actions>types.js
export const LOGIN_USER = 'login_user'; export const REGISTER_USER = 'register_user';
src>reducers>user_reducer.js
import { LOGIN_USER, REGISTER_USER } from '../actions/types'; export default function( state = {}, actions){ switch(actions.type){ case LOGIN_USER: return { ...state, loginSuccess: actions.payload} case REGISTER_USER: return { ...state, loginSuccess: actions.payload} default: return state; } }
functional 방식을 이용한 것은 다음과 같다.
import React, { useState } from 'react' import { useDispatch } from 'react-redux'; import { registerUser } from '../../../_actions/user_action'; import Axios from 'axios'; import { withRouter } from 'react-router-dom'; function RegisterPage(props) { const dispatch = useDispatch(); const [Email, setEmail] = useState("") const [Name, setName] = useState("") const [Password, setPassword] = useState("") const [ConfirmPassword, setConfirmPassword] = useState("") const onEmailHandler = (event) => { setEmail(event.currentTarget.value) } const onNameHandler = (event) => { setName(event.currentTarget.value) } const onPasswordHandler = (event) => { setPassword(event.currentTarget.value) } const onConfirmPasswordHandler = (event) => { setConfirmPassword(event.currentTarget.value) } const onSubmitHandler = (event) => { event.preventDefault(); if (Password !== ConfirmPassword) { return alert('비밀번호와 비밀번호 확인은 같아야 합니다.') } let body = { email: Email, password: Password, name: Name } dispatch(registerUser(body)) .then(response => { if (response.payload.success) { props.history.push("/login") } else { alert("Failed to sign up") } }) } return ( <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' , width: '100%', height: '100vh' }}> <form style={{ display: 'flex', flexDirection: 'column' }} onSubmit={onSubmitHandler} > <label>Email</label> <input type="email" value={Email} onChange={onEmailHandler} /> <label>Name</label> <input type="text" value={Name} onChange={onNameHandler} /> <label>Password</label> <input type="password" value={Password} onChange={onPasswordHandler} /> <label>Confirm Password</label> <input type="password" value={ConfirmPassword} onChange={onConfirmPasswordHandler} /> <br /> <button type="submit"> 회원 가입 </button> </form> </div> ) } export default withRouter(RegisterPage)
생성된 파일들은 아래의 깃헙에서 확인할 수 있다.
https://github.com/jaewonhimnae/boilerplate-mern-stack
'NODE.JS' 카테고리의 다른 글
Youtube 만들기 - 3) 비디오 업로드 Form 만들기 2 (0) 2021.05.14 Youtube 만들기 - 2) 비디오 업로드 Form 만들기 1 (0) 2021.05.14 MERN 기본파일 만들기 - 12) Login Page 만들기 (0) 2021.05.13 MERN 기본파일 만들기 - 11)antd 디자인 사용하기, redux 사용하기, React-Hooks (0) 2021.05.13 MERN 기본파일 만들기 - 10) proxy, concurrently 사용하기 (0) 2021.05.13