NODE.JS

MERN 기본파일 만들기 - 13)Register Page 만들기

dodop 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

 

jaewonhimnae/boilerplate-mern-stack

Boilerplate when you use REACT JS, MONG DB, EXPRESS JS, REDUX - jaewonhimnae/boilerplate-mern-stack

github.com