City At Night

[MernStack] Blog 만들기 16. [React] 로그인구현을 위한 Reducer setting 본문

MernStack

[MernStack] Blog 만들기 16. [React] 로그인구현을 위한 Reducer setting

Wuny 2021. 6. 18. 01:39
728x90
반응형

이제는 로그인 기능을 구현하겠다.
로그인의 기능을 대충 세분화하면

1. 아이디와 비밀번호등 인증을 서버로 요청하고
2. 서버에서는 인증에대한 성공 또는 실패에 관한 결과를 응답해준다.

이번 포스팅에선
클라이언트쪽에서 서버로 인증을 서버로 요청할때 상태,
서버에서 인증에대한 성공 응답에 대한 상태
 또는
서버에서 인증에대한 실패 응답에 대한 상태 관리를  기능적으로 구현하겠다.

 

1.로그인상태 및 에러 클리어 Type 설정

redux폴더에 types.js를 생성한다.

[redux/types.js]

//LOGIN
export const LOGIN_REQUEST = "LOGIN_REQUEST"
export const LOGIN_SUCCESS = "LOGIN_SUCCESS"
export const LOGIN_FAILURE = "LOGIN_FAILURE" 

// CLEAR ERROR
export const CLEAR_ERROR_REQUEST = "CLEAR_ERROR_REQUEST"
export const CLEAR_ERROR_SUCCESS = "CLEAR_ERROR_SUCCESS"
export const CLEAR_ERROR_FAILURE = "CLEAR_ERROR_FAILURE" 

types.js에서는 로그인 요청,성공, 실패에 대한 타입과 에러를 클리어했을때의 타입을 정의한다.

 

2. 상황에 맞는 상태관리 작성

[redux/reducers/authReducer.js ]

const initialState = {
    token:localStorage.getItem('token'),
    isAuthenticated: null,
    isLoading: false,
    user: "",
    userId:"",
    userName:"",
    userRole:"",
    errorMsg:"",
    successMsg:"",
}

이부분은 현재 상태 기본값을 설정하는 부분이다.
기본값은 다 null 또는 빈값으로 넣어준다.
store.js 에서 선언한 initialState를 사용한다.
strore.js는 웹에 모든 상태를 담고 있는 초기값을 저장하는 부분이다.
자세한 내용은 11번 포스팅 참고.

const authreducer = (state = initialState, action) => {
    switch(action.type){
        case LOGIN_REQUEST:
            return {}
        case LOGIN_SUCCESS:
			return {}
        case LOGIN_FAILURE:
			return {}
        case CLEAR_ERROR_REQUEST:
			return {}
        case CLEAR_ERROR_SUCCESS:
            return {}
        case CLEAR_ERROR_FAILURE:
            return {}
        default:
            return state
    }
}
export default authreducer

authreducer함수를 만들고 state라는 변수에 현재 상태 기본값을 넣어준 initialState로 초기화 시켜주고
switch문으로 위에서 작성했던 로그인 상태에 관한 type들 받아준다.
(Login_Success,Failure.. 등등..)

 

각 타입마다 동작할 return값을 작성한다.

const authreducer = (state = initialState, action) => {
    switch(action.type){
        case LOGIN_REQUEST:
            return {
                ...state, //... 은 얕은 복사를 의미함
                errorMsg:"",
                isLoading: true 
            }
        case LOGIN_SUCCESS:
            localStorage.setItem("token", action.payload.token) //서버에서 인증토큰값을 가져온다(jwt)
            return{
                ...state,
                ...action.payload,
                isAuthenticated: true,
                isLoading: false,
                userId: action.payload.user.userId,
                userRole : action.payload.user.role,
                errorMsg:""
            }

        case LOGIN_FAILURE:
            localStorage.removeItem("token") // 로그인이 실패하였으므로 token을 제거함
            return{
                ...state,
                ...action.payload,
               token : null,
               user : null,
               userId: null,
               isAuthenticated: false,
               isLoading : false,
               userRole: null,
               errorMsg: action.payload.data.msg
            }
        case CLEAR_ERROR_REQUEST:
            return{
                ...state,
                ERRORmSG: null,
            }
        case CLEAR_ERROR_SUCCESS:
            return{
                ...state,
                ERRORmSG: null,
            }
        case CLEAR_ERROR_FAILURE:
            return{
                ...state,
                ERRORmSG: null,
            }
        default:
            return state
    }
}
export default authreducer

...state에서 ...은 얉은 복사를 의미한다.
state값을 복사하는 이유는 기존의 state값과 현재 바뀐 state값을 비교하여 
바뀐 부분만 반영하기 위해서이다.

 

[redux/reducers/authReducer.js ] 전체코드

import { NULL } from 'node-sass'
import { CLEAR_ERROR_FAILURE, CLEAR_ERROR_REQUEST, CLEAR_ERROR_SUCCESS, LOGIN_FAILURE, LOGIN_REQUEST, LOGIN_SUCCESS } from '../types'

const initialState = {
    token:localStorage.getItem('token'),
    isAuthenticated: null,
    isLoading: false,
    user: "",
    userId:"",
    userName:"",
    userRole:"",
    errorMsg:"",
    successMsg:"",
}

const authreducer = (state = initialState, action) => {
    switch(action.type){
        case LOGIN_REQUEST:
            return {
                ...state, 
                errorMsg:"",
                isLoading: true 
            }
        case LOGIN_SUCCESS:
            localStorage.setItem("token", action.payload.token) 
            return{
                ...state,
                ...action.payload,
                isAuthenticated: true,
                isLoading: false,
                userId: action.payload.user.userId,
                userRole : action.payload.user.role,
                errorMsg:""
            }

        case LOGIN_FAILURE:
            localStorage.removeItem("token")
            return{
                ...state, 
                ...action.payload,
               token : null,
               user : null,
               userId: null,
               isAuthenticated: false,
               isLoading : false,
               userRole: null,
               errorMsg: action.payload.data.msg
            }
        case CLEAR_ERROR_REQUEST:
            return{
                ...state,
                ERRORmSG: null,
            }
        case CLEAR_ERROR_SUCCESS:
            return{
                ...state,
                ERRORmSG: null,
            }
        case CLEAR_ERROR_FAILURE:
            return{
                ...state,
                ERRORmSG: null,
            }
        default:
            return state
    }
}
export default authreducer



이제는 로그인시 발생할 상황에 대해 기능적으로 구현을 했으니 
다음 포스팅에서는 모달창이라는 것을 활용하여 로그인창을 띄워 로그인기능과 연동 시켜보겠다.


 

728x90
반응형
Comments