[TIL] Redux

전역 상태 관리 라이브러리

1. 디자인 패턴

  • 소프트웨어 개발을 할 때 자주 쓰이는 모범 답안 같은 설계 양식

MVC 패턴

Model, View, Controller

  • 관심사의 분리로 코드가 단순해지고, 유지보수 시 더 높은 수준의 자유가 생긴다.
  • 페이스북에서는 MVC 패턴 사용시 양방향 바인딩 때문에 어떤 컨트롤러가 어떤 요소에 영향을 주었는지 알기 어려운 단점이 있다고 판단하고 Flux 개발
  • Flux는 단방향!

2. Redux

자바스크립트 앱을 위한 예측 가능한 상태 컨테이너

  • 리덕스 구성요소
    • Action: 명령
    • Dispatcher: 명령 전달
    • Store: 저장소
    • View: 화면 UI
  • 데이터의 흐름은 복잡하기 때문에 데이터의 흐름을 제약할 필요가 있다.
  • 상태 변화가 일어나는 시점과 형태에 제약을 두어 상태 변화를 예측 가능하게 만들고자 했다.
  • 단방향 데이터 바인딩을 하는 Flux 패턴의 자바스크립트 구현체

Redux의 3가지 원칙

  1. 진실은 하나의 소스로부터

    • 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장
  2. 상태는 읽기 전용

    • 리덕스의 상탯값 수정 방법: 액션 객체와 함께 dispatch 호출
    • 업데이트의 방식과 시점 제한으로 변화에 대한 예측 가능성을 얻을 수 있음
      • Dispatch가 호출된 순서대로 상태를 변경하여 변경된 순서와 내역 쉽게 관리
      • Action 객체는 평범한 자바스크립트 객체이며, 이 객체가 Store에 입력된 순서와 내용을 저장해두면 나중에 그 과정을 쉽게 재현 가능
  3. 변화는 순수 함수로 작성

    순수 함수: 어떤 함수에 동일한 인자를 주었을 때 항상 같은 값을 리턴하는 함수

    • 리듀서는 이전 상탯값과 액션 객체를 입력으로 받아 새로운 상탯값을 만드는 순수 함수
    • 순수 함수는 테스트 코드를 작성하기 쉽다 ➡ 같은 입력에 같은 출력
    • fetch 등의 비동기 로직, new Date(), Math.random()은 같은 input에 다른 return값을 주므로 유닛 테스트 불가!

Redux Concenpts

  1. View

    • 화면 UI
  2. Action / Action Creator

    • Action: 상태 변화에 대한 의도를 표현하는 단순한 자바스크립트 객체
    • Action Creator: Action객체를 정해진 틀에 맞게 리턴하는 단순한 함수
    export const addCart = (item) => {  // 액션 생성 함수
        return {
            type: "ADD_ITEM",  // 액션 객체, 필수적으로 필요
            payload: itme,  // 전달할 데이터
        };
    };
  3. Dispatcher

    • Action 객체를 Reducer에 전달하는 역할을 하는 함수. store.dispatch(액션) 형태
    • 기본 dispatch 함수는 반드시 동기적으로 처리되어야 한다.
  4. Reducer

    • reduce() 메서드처럼 값을 받아서 하나의 결과물로 줄인다.
    • (previousState, action) => newState의 형태의 순수함수이며 예측 가능해야 한다.
    • 업데이트 이전의 Store를 기반으로 새로 받은 Action에 미리 준비된 로직을 처리하여 새로운 Store를 리턴하는 함수
    • Root Reducer: 실제로 createStore의 첫 번째 인자로 전달되는 함수. 유일하게 (state, action) => newState형태의 로직을 가져야 한다.
    • Slice Reducer: 상태 트리의 일부분만 업데이트하는 리듀서. 여러 개가 결합되어 Root Reducer가 된다.
    • 주의 사항
      • 불변성을 지켜서 업데이트하기
      • Reducer 내부에서 비동기나 순수하지 않은 로직(Side Effect) 처리 불가
  5. Store

    • Redux 앱 전체의 상태는 보통 깊게 중첩되어 있는 객체
    • store에서 관리되며 store.getState()로 읽기 가능
    • 항상 직렬화 가능해야 하므로 JSON으로 변환 가능한 것들만 포함시키자
  6. 미들웨어

    • 미들웨어를 설정하지 않으면 액션이 곧바로 리듀서로 보내진다.
    • 예) redux-logger, redux-thunk, redux-saga

3. React-Redux

React에서 Redux를 사용하는 이유

  1. 전역 상태 관리
    • 여러 컴포넌트에 걸친 변화
    • 멀리 떨어진 컴포넌트 간의 통신이 어려움
  2. props drilling
    • 코드 파악하기 어려움
    • 불필요한 렌더링 발생

react-redux의 역할

  • Redux의 여러 기능들을 React의 API에 맞도록 감싼 UI Binding 라이브러리
    • 예) store➡Provider 컴포넌트를 사용해 전역에 store 주입 (내부적으로 context API 사용)
    • 예) useSelector, useDispatch 등 React 전용 hooks 제공

Redux 패턴에 맞는 프로젝트 폴더 구조

  • Ducks pattern
    • Action Type, Action, Reducer 모두 하나의 파일 안에서 관리하는 패턴
    • 기능별로 나누는 방식

좋은 웹페이지 즐겨찾기