프론트엔드 개발/React

Redux-Toolkit 상태관리 라이브러리 사용법

Ella Seon 2023. 8. 30. 21:30

0. Redux 등장배경

- MVC 패턴(양방향 데이터 흐름)이 주류였지만, 양방향 데이터 흐름은 복잡하고 데이터 흐름을 판단하기 불편했다. 이러한 해결방법으로 단방향 데이터 흐름인 Redux 가 등장했다. 

 

🔸MVC 패턴(양방향 데이터 흐름)

- 어떤 action 이 발생하면 데이터 상태가 변경되고 그에 따라 디스플레이를 변경하는데 상태가 변경되었다는 정보를 View와 Model이 서로 양방향으로 주고 받는 형태이다. 

1) Model : 어플리케이션의 데이터를 관리해주는 부분

2) View : 어플리케이션이 사용자에게 어떻게 보여지는지에 대한 관리

3) Controller : Model 의 자료와 View의 인터렉션을 총괄하는 어플리케이션 로직

그러나 몇몇 사람들이 MVC가 대규모 어플리케이션 개발에는 관리하기 어렵다고 느끼기 시작했다. 프로젝트가 단순하다면 위 그림처럼 간단하게 표현될 수 있다. 그러나 프로젝트 규모가 커지면 데이터 자료의 양과 화면이 많아지면서 Model과 View가 급격히 늘어나고 그에 따라 각각의 모듈들이 어떤 식으로 연결되어있는지 파악하기가 매우 어려워지기 마련이다.

 

🔸FLUX 패턴(단방향 데이터 흐름)

View는 MVC 패턴과 달리 데이터를 변경시키지 않고, Action을 넘겨준다. 이때 Action은 반드시 Dispatcher을 통해서 데이터가 변경된다. 변경된 데이터를 Store을 통해서 View가 전달받는다. 

 

전역상태를 전부 하나의 저장소(store)안에 있는 객체 트리에 저장하며, 상태를 변경하는 것은 어떤 일이 일어날지 서술하는 객체인 action 을 내보내는(dispatch) 것이 유일한 방법이다. 그리고 액션이 전체 애플리케이션의 상태를 어떻게 변경할지 명시하기 위해서는 리듀서 작성이 필요하다. 

 

1. Redux 는 보일러플레이트가 너무 많아

- 액션 타입, 액션 생성함수, 리듀서 3가지 종류로 코드를 준비해야한다.

- 세부적인 업데이트가 늘어날 수록 불변성을 지키기 위하여 ...state를 사용하는 것도 번거롭다. 

// 액션 타입 설정
export const OPEN = 'msgbox/OPEN';
export const CLOSE = 'msgbox/CLOSE';

// 액션 생성함수
export const open = (message) => ({ type: OPEN, message });


// 초기 상태
const initialState = {
  open: false,
  message: '',
};

//reducer 정의
export default msgboxReducer(state = initialState, action) {
  switch (action.type) {
    case OPEN:
      return { ...state, open: true, message: action.message };
    case CLOSE:
      return { ...state, open: false };
    default:
      return state; // 알 수 없는 액션 타입이 들어올경우 현재 상태 그대로 반환
  }
}

2. Redux-toolkit

🔸등장배경

- 리덕스 스토어 환경 설정은 너무 복잡하고, 보일러플레이트(어떤 일을 하기위해 꼭 작성해야하는 상용구 코드)를 너무 많이 요구한다.

- Immer 가 내장되어있기 때문에 불변성을 유지하기 위해 번거로운 코드를 작성하지 않고 원하는 값을 직접 변경하면 알아서 불변성이 유지되면서 상태가 업데이트 된다. 

- 이러한 단점을 해결하기 위해 리덕스 툴킷이 등장하고 공식문서에서도 리덕스 로직을 작성하는 표준 방식이 되기 위한 의도로 만들어졌다고 한다.

 

🔸기본적인 counter 앱 만들어보기

1) Redux slice 생성

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
      increment: (state) => {
      return state + 1;
    },
    decrement: (state) => {
      return state - 1;
    }
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

- initialState를 통해 state의 처음 상태를 정의한다.

- 초기값을 변경하고 싶으면 reducers에서 액션(state 변경함수)을 설정한다. (increment,decrement)

- increment와 decrement 를 export 한다.

- slice는 slice.reducer로 내보낸다. 

2) 스토어 생성

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

export default store;

3) 리액트 컴포넌트 생성

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

const Counter = () => {
  const count = useSelector(state => state.counter);
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(decrement())}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
};

export default Counter;

- useSelector() 는리덕스의 상태를 조회할 수 있다.

- useDispatch() 는 생성한 액션을 발생시키며, 액션 생성함수를 가져온다. 

 

4) 앱에 스토어 연결

import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './Counter';

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

export default App;

 

 

 


참고자료

https://itprogramming119.tistory.com/entry/React-%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%B4%9D%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EC%98%88%EC%A0%9C

 

[React] 리덕스 총정리 및 예제

[Redux란?] 1. Redux 등장 배경 MVC 패턴 형식으로 state가 변화되면 Model, View, Controller에 이벤트가 발생하고 값이 변화하는 구조였습니다. 즉, 양방향 데이터 흐름이었죠. 양방향 데이터 흐름은 복잡하

itprogramming119.tistory.com

https://bestalign.github.io/translation/cartoon-guide-to-flux/

 

Flux로의 카툰 안내서

원문: https://medium.com/code-cartoons/a-cartoon-guide-to-flux-6157355ab207 Flux…

bestalign.github.io

https://kjwsx23.tistory.com/552

 

[React, Redux] 내가 리덕스를 쓰지 않는 이유

안녕하세요, Einere입니다. (광고차단 기능을 꺼주시면 감사하겠습니다.) 해당 포스트는 Why I Stopped Using Redux를 번역한 글입니다. 리덕스는 리액트 환경에서 혁신적인 기술입니다. 리덕스는 불변

kjwsx23.tistory.com

https://velog.io/@qf9ar8nv/%EA%B0%84%EB%8B%A8%ED%95%9C-%EC%98%88%EC%A0%9C%EB%A5%BC-%ED%86%B5%ED%95%B4-Redux%EB%A5%BC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

 

간단한 예제를 통해 Redux를 이해하기

현재 진행하는 토이 프로젝트에 react + mobx를 사용하기로 했는데, 아직 react의 상태관리에 대해 이해가 잘 되지 않아서 가장 널리 알려진 redux부터 공부를 시작했습니다..😂간단한 redux 예제도 클

velog.io

https://react.vlpt.us/redux/03-prepare.html