ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MERN 기본파일 만들기 - 12) Login Page 만들기
    NODE.JS 2021. 5. 13. 15:05

     

     

     

    컴포넌트 안의 registerlogin을 이용할 것이다. 

    App.js에 라우터를 등록해 놓는다. 

    import React from 'react';
    import {Route, Switch} from "react-router-dom";
    import About from "./about"//index.js가 기본이기 때문에 굳이 타이핑하지 않아도 된다.
    import LoginPage from "./RegisterLogin/LoginPage";
    import RegisterPage from "./RegisterLogin/RegisterPage";
    import LandingPage from "./
    
    
    function App() {
      return (
        <div >
          <Switch>
            {/* <Route path="/" component={Home} /> */}
            <Route path = "/" component={LandingPage}/>
            <Route path = "/login" component={LoginPage}/>
            <Route path = "/register" component={RegisterPage}/>
    
          </Switch>
        </div>
      );
    }
    
    export default App;
    

     

     

     

    먼저 class 방식을 보자. 

    src>components>RegisterLogin>index.js

    import React, { Component } from 'react'
    
    class RegisterLogin extends Component {
    }
    export default connect(mapStateToProps)(RegisterLogin);

     

     

     

     

    css 스타일링은 materialize를 이용한다.

    https://materializecss.com/getting-started.html

     

    Getting Started - Materialize

    Materialize comes in two different forms. You can select which version you want depending on your preference and expertise. To start using Materialize, all you have to do is download one of the options below.

    materializecss.com

     

     

    client에 npm install materialize-css@next --save해준다.

     

     

    그다음 src>components>registerLogin>index.js를 다음과 같이 바꾼다.

    handleChange 는 값을 입력하면 그대로 바로 화면에 보여주게끔 해주는 함수이고, 

    submitForm은 들어온 값이 validate하다면 데이터를 보내서 아이디와 비밀번호가 맞는지 확인하고 

    isFormvalid는 입력한 형식이 맞는지 확인하는 함수이다. 

     

     

    event.preventDefault()는 창 새로고침이 계속되는 것을 막아준다.

     

     

     

     

    import React, { Component } from 'react'
    import {connect} from 'react-redux';
    import {loginUser} from '../../actions/user_actions';//actions에서 response를 가지고 있기 때문에 loginUser를 가져온다.
    import {Link} from 'react-router-dom';
    
    
    class RegisterLogin extends Component {
    
        state = {
            email:"",
            password: "",
            errors:[]
        
        }
        displayErrors = errors=>{
            errors.map((error, i)=><p key={i}>{error}</p>)
        }
        handleChange = event =>{
            this.setState({[event.target.name]: event.target.value})
        }
    
        submitForm = event=>{
            event.preventDefault();
    
            let dataToSubmit = {
                email:this.state.email,
                password:this.state.password
            };
    
            if(this.isFormvalid(this.state)){
                this.setState({errors:[]})
                    this.props.dispatch(loginUser(dataToSubmit))//actions의 함수 loginUser
                        .then(response=>{
                            if(response.payload.loginSuccess){
                                this.props.history.push('/')
                            }else{
                                this.setState({errors: this.state.errors.concat("Failed to log in, you can check your email and password")})
                            }
                        }
                            
                        )
    
                
            }else{
                this.setState({
                    errors: this.state.errors.concat('Form is not valid')
                })
            }
        }
    
    
        isFormvalid=({email, password}) => email && password;
    
        // const {email} = this.state;
        // const email = this.state.email; 위아래는 같은 뜻이다. 
    
        render() {
            return (
                <div className="container">
                    <div className="row">
                        <h2>Login</h2>
                        {/* 전체 사이즈 사용하려면 12사용한다.  */}
                        <form className="col s12" onSubmit={event =>this.submitForm(event)}>
                            <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 htmlFor = "email">Email</label>
                                        <span
                                            className="helper-text"
                                            data-eroor="Type a right type email"
                                            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 htmlFor = "password">Email</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}
                                    >Login
                                    </button> &nbsp; &nbsp;
                                    {/* a href 는 계속 새로 새로고침하고 Link는 하지 않는다.*/}
                                    <Link to = "/register">
                                    <button
                                        className="btn waves-effect red lighten-2"
                                        type="submit"
                                        name = "action"
                                    >Sign up
                                    </button>
                                    </Link>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            )
        }
    }
    
    function mapStateToProps(state){
        return {
            user:state.user
        }
    }
    export default connect(mapStateToProps)(RegisterLogin);

     

     

     

    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)
    
    
    	//리듀서는 들어온 정보와 현재정보를 조합하여 다음 조합을 리턴한다. (액션은 response와 타입을 피요로 하므로 다음과 같이 넣어준다)
        
        return {
            type:LOGIN_USER,
            payload: request
        }
                        
    
    };
    
    

     

     

    src>actions>types.js

    //타입만 관리하는 type파일
    export const LOGIN_USER = 'login_user';
    

     

     

    reducer>user_reducers.js

    import {
        LOGIN_USER,
    } from '../actions/types';
    
    
    export default function( state = {}, actions){//전 state와 action가지고 다음 step을 만든다
    
    
        switch(actions.type){//타입에 따라서 다른 처리 한다. 
    
            case LOGIN_USER: 
                return { ...state, loginSuccess: actions.payload}
           
            default:
                return state;
        }
    }

     

     

     

     

     


     

    이번엔 functional 방식으로 진행해보자. 

     

    LoginPage.js는 다음과 같다.

    import React, { useState } from 'react'
    import Axios from 'axios'
    import { useDispatch } from 'react-redux';
    import { loginUser } from '../../../_actions/user_action';
    import { withRouter } from 'react-router-dom';
    
    function LoginPage(props) {
    
    
        const dispatch = useDispatch();
    
        const [Email, setEmail] = useState("")
        const [Password, setPassword] = useState("")
    
        const onEmailHandler = (event) => {
            setEmail(event.currentTarget.value)
        }
    
        const onPasswordHandler = (event) => {
            setPassword(event.currentTarget.value)
        }
    
        const onSubmitHandler = (event) => {
            event.preventDefault();
    
            let body = {
                email: Email,
                password: Password
            }
    
    		//서버에 보낼것인데, axios를 리덕스를 이용해서 진행할 것이다. 
            dispatch(loginUser(body))
                .then(response => {
                    if (response.payload.loginSuccess) {//성공하면 메인페이지로 이동
                        props.history.push('/')
                    } else {
                        alert('Error˝')
                    }
                })
    
    
        }
    
    
        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>Password</label>
                    <input type="password" value={Password} onChange={onPasswordHandler} />
                    <br />
                    <button type="submit">
                        Login
                    </button>
                </form>
            </div>
        )
    }
    
    export default withRouter(LoginPage)

    RegisterPage.js는 다음과 같다

    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)

     

     

     

     

     

Designed by Tistory.