본문 바로가기
Web/React Node js

리액트 기초 강의 (9) - 로그인 페이지

by SeleniumBindingProtein 2022. 3. 2.
728x90
반응형

- 현재 Boiler Plate는 로그인과 회원가입 부분을 Formik과 Yup이란 라이브러리를 사용해서 좀 더 다이나믹하게 만들었음

- 그러나, 참고 강의가 기초 강의 수업이므로 기본 기능을 가진 로그인 페이지를 만들 예정.

 

 - LandginPage & LoginPage 생성

import React, {useEffect} from 'react';
import axios from 'axios';

function LandingPage(){

    useEffect(() => {
        axios.get('/api/hello').then(response => console.log(response.data))
    }, [])

    return (
        <div style={{
            display:'flex', justifyContent:'center', alignItems:'center', width:'100%', height:'100vh'
        }}>
            <h2>시작 페이지</h2>
        </div>
    )
}

export default LandingPage;

- 이메일과 패스워드를 타이핑이 안되서, state를 정의하고, setState함수를 이용하여 값이 변했을 때 적용시켜 주면 됨

- 이후, form에 submit event를 적용시키면 되고, 그렇기 위해서는 button에 type을 submit이라 지정해주고

   Axios를 이용해 서버에 데이터를 보내면 되지만 Redux를 사용하기 때문에 좀 더 작업이 필요함

- redux를 사용하려면 action을 reducer에게 전달하여 nextState를 store에 업데이트해야 함

import { Axios } from 'axios';
import React, { useState } from 'react';
import {useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_actions';
import {useNavigate} from 'react-router-dom';

function LoginPage(){
    const navigate = useNavigate();
    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();

        console.log('Email',Email)
        console.log('Password',Password)

        let body = {
            email: Email,
            password: Password
        }

        dispatch(loginUser(body))

    }

    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 LoginPage;

- user_actions.js

- onsubmitHandler를 보면 Redux를 사용하지 않으면 Axios를 이용해 서버에 전달하기만 하면 됨
- 하지만 Redux를 사용하기 위해서는 dispatch를 사용하여 store에 데이터를 업데이트해야 함

- dispatch에게 action을 전달하면 되는데 이는 _action 디렉토리에 정의하면 됨

import axios from 'axios';
import {
    LOGIN_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
    }
}

 - types.js

 - user_action이며, action에는 여러 타입이 있을 수 있기 때문에 type을 정의하여 관리하고,
    서버에 request를 보낸 뒤 response를 받아 request 변수에 저장한 뒤 reducer에 보내는 것

export const LOGIN_USER = "login_user";

- user_reducer

- 현재 state는 비어있는 상태이고 스프레드 오퍼레이터를 사용하여 특정 객체를 새로운 객체로 복사하는 것을 의미하며, 

    state를 복제하여 그대로 사용하겠다는 의미이고, loginSuccess에 전달받은 payload를 넣어 return함

import{
    LOGIN_USER
} from '../_actions/types';


export default function(state={}, action){
    switch (action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload}
            break;
    
        default:
            return state;
    }
}

 - 미리 가입해놓은 계정이 DB에 있고 똑같은 값을 입력하여 로그인을 성공적으로 완료


- action에서 서버에 보낸 request에 대한 response를 request에 저장하여 payload라 네이밍하여 return 했고,

- reducer에서 next state를 만드는 것이고, 이제 로그인에 성공했으니 LandingPage로 전송

import { Axios } from 'axios';
import React, { useState } from 'react';
import {useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_actions';
import {useNavigate} from 'react-router-dom';

function LoginPage(){
    const navigate = useNavigate();
    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();

        console.log('Email',Email)
        console.log('Password',Password)

        let body = {
            email: Email,
            password: Password
        }

        dispatch(loginUser(body))
            .then(response => {
                if(response.payload.loginSuccess){
                    navigate('/')
                } 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 LoginPage;

 

 => 버젼 5에서는 props.history.push를 이용하여 로그인이 성공하면 LandingPage로 이동하게 하였지만, 

       버젼 6에서는 navigate로 대체되어 사용됨으로 push 사용시 주의 해야함 

- 참고자료

https://www.digitalocean.com/community/tutorials/react-react-router-v6

 

A Sneak Peek at React Router v6 | DigitalOcean

 

www.digitalocean.com

 

728x90
반응형

댓글