[Redux Tutorial] Login page 만들며 Redux 이해하기

2022. 9. 13. 01:38·Frontend/React

누구 알려주려고 쓰는 튜토리얼 아님. 개인 기록용. (John Ahn 님의 따라하며 배우는 노드, 리액트 강의를 보며 작성하였음)


1. Redux 라이브러리 설치

Redux를 쓰려면 라이브러리 다운로드를 해야 한다.

npm install redux react-redux redux-promise redux-thunk --save

redux-promise와 redux-thunk는 action이 객체가 아니라 promise, function이어도 dispatch할 수 있게 해주는 라이브러리이다.

 

 

2. index.js 수정

index.js에 아래 내용을 추가한다.

import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers/index';

const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore)

// 아래는 냅다 추가하지 말고 Provider 태그 이하의 것들만 추가하면 된다.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider
    store={createStoreWithMiddleware(Reducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ &&
      window.__REDUX_DEVTOOLS_EXTENSION__()
    )}>
    <App />
  </Provider>
);

 

 

3. action, reducer 폴더 및 파일 만들기

src 폴더 내에 '_reducers' 폴더를 만들고, 'index.js'와 'user_reducer.js' 파일을 만든다. index.js 내용은 이렇게 채워준다. user_reducer.js 파일은 6번에서 채워줄 것이다.

_reducers/index.js

import { combineReducers } from "redux";
import user from './user_reducer';

const rootReducer = combineReducers({
    user,
})

export default rootReducer;

 

 

4. Login을 위한 정보 요청 작업 Dispatch

Login을 하기 위해 email, password를 쓴 다음 '로그인' 버튼을 눌렀을 때, 서버에게 정보를 요청하는 작업을 대충 이런 식으로 짤 수 있다.

LoginPage.js

import { useDispatch } from 'react-redux';
import { loginUser } from '../../../_actions/user_action';

// '로그인' 버튼을 눌렀을 때 처리할 일들
const onSubmitHandler = (event) => {
    event.preventDefault();	// 로그인 버튼이 눌릴 때마다 refresh가 일어나는데,
    						// refresh해도 아래 코드들이 진행되게 해줌
    let body = {
            email: email,
            password: password
    }
    
    dispatch(loginUser(body))	// 서버에 로그인을 요청하는 작업을 dispatch
    /* Redux를 안쓰는 경우
    axios.post('/api/users/login', body)
            .then(response => response.data)	// backend에서 정한 login route로 body를 보냄
    */
}

 

src 폴더 내에 action을 위한 폴더 '_actions'를 만들고, 'user_action.js' 파일을 만든다.

_actions/user_action.js

import axios from 'axios';

export function loginUser(dataToSubmit) {
    const request = axios.post('/api/users/login', dataToSubmit)
        .then(response => response.data)    //request에 받아온 data를 저장함

    // reducer로 이 action을 넘겨줌
    return {
        type: "LOGIN_USER",
        payload: request
    }
}

 

 

 

 

5. Action type 관리를 위한 파일 만들기

_actions 폴더 내에 types.js 파일을 만든다. action이 지금은 하나지만, 나중에 엄청 많아질 수 있고, 그럼 action type도 많아질 수 있다. 관리하기 좋게 types.js 파일 안에서만 type을 만들기로 하고, 다른 곳에서는 요 types.js를 import해서 쓰도록 한다.

_actions/types.js

// type은 여기에서만 지정할 수 있도록, action type 관리하는 파일
export const LOGIN_USER = "login_user";

 

user_action 파일을 아래와 같이 수정한다.

_actions/user_action.js

import axios from 'axios';
import { LOGIN_USER } from './types'	// types.js import

export function loginUser(dataToSubmit) {
    const request = axios.post('/api/users/login', dataToSubmit)
        .then(response => response.data)

	// action type을 아래와 같이 바꿔줌
    return {
        type: LOGIN_USER,
        payload: request
    }
}

 

 

6. Reducer 만들기

_reducer/user_reducer.js

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

export default function (state = {}, action) {
    // type이 아주 많아질 수 있으므로 switch를 써줌
    switch (action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload }

        default:
            return state;
    }
}

 

 

7. Login page에서 응답 처리하기

6번 reducer에서 loginSuccess를 받아서 만약 로그인에 성공했다면 자동으로 home으로 돌려보내고, 실패했다면 에러창을 띄워주도록 한다. 그러기 위해서 useNavigate를 import하고, 컴포넌트 내에 navigate 변수를 만든다.

import { useNavigate } from 'react-router-dom';
// 컴포넌트 또는 함수 내에 navigate 변수 선언
let navigate = useNavigate();

 

그리고 dispatch 부분을 아래와 같이 수정한다.

dispatch(loginUser(body))
	.then(response => {
	if (response.payload.loginSuccess) {
    	navigate('/');
    } else {
    	alert('Error');
    }
})

 

 

8. 테스트

Chrome 확장 프로그램 "Redux DevTools"를 사용해 테스트했다.

아직 회원가입 기능을 안 만들었기 때문에, 이미 DB에 있는 email과 password를 입력하고 로그인 버튼을 눌러준다. 아래는 정상적으로 작동했을 때 Redux DevTools를 사용하면 볼 수 있는 화면이다. Test 결과는 아래와 같다.

import reducers from '../../reducers';

test('reducers', () => {
  let state;
  state = reducers({user:{}}, {type:'login_user',payload:{loginSuccess:true,userId:'631f4731e0fdf6a6262fa554'}});
  expect(state).toEqual({user:{loginSuccess:{loginSuccess:true,userId:'631f4731e0fdf6a6262fa554'}}});
});

 

Action

4번에서 action을 만든 것과 같이 type과 payload 형태로 되어있고, payload는 request에 대한 response.data로 되어있다.

 

state

Reducer로 state가 위와 같이 바뀌었음을 확인할 수 있다.

저작자표시 (새창열림)

'Frontend > React' 카테고리의 다른 글

리액트의 이벤트 처리 방식 까보기  (0) 2025.03.11
useState의 setState에 함수 넣기 (Functional Update)  (0) 2023.08.17
[react] 달력 만들기 01  (0) 2023.01.31
[HOC] about HOC(Higher Order Component)  (0) 2022.09.13
[Redux Tutorial] about Redux  (0) 2022.09.13
'Frontend/React' 카테고리의 다른 글
  • useState의 setState에 함수 넣기 (Functional Update)
  • [react] 달력 만들기 01
  • [HOC] about HOC(Higher Order Component)
  • [Redux Tutorial] about Redux
톱치
톱치
나를 위한 기록을 합니다
  • 톱치
    기록
    톱치
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
    • 전체보기 (51)
      • Articles (0)
      • Frontend (3)
        • JS, TS (16)
        • HTML, CSS (5)
        • React (6)
        • Dart (3)
      • Backend (6)
      • Others (3)
      • Algorithm (5)
      • 회고 (4)
  • 링크

    • GitHub
  • 태그

    BFS
    회고
    object
    login
    TypeScript
    programmers
    BCrypt
    ts
    우아한테크코스
    token
    React
    Node
    node.js
    Redux
    프리코스
    javascript
    js
    todolist
    dart
    css
  • hELLO· Designed By정상우.v4.10.3
톱치
[Redux Tutorial] Login page 만들며 Redux 이해하기
상단으로

티스토리툴바