Redux

» REACT

Redux란?

리액트 생태계에서 가장 사용률이 높은 상태 관리 라이브러리
컴포넌트들의 상태 관련 로직들을 다른 파일들로 분리시켜서 효율적으로 관리할 수 있으며 글로벌 상태 관리도 쉽게 할 수 있음
그래서 프로젝트가 큰 규모에서 주로 사용됨

  • contextAPI를 사용하는 것과의 차이
    미들웨어라는 개념이 있는데 아래와 같은 작업을 할 수 있다

    • 특정 조건에 따라 액션을 무시하게 만듬
    • 액션을 콘솔에 출력하거나, 서버쪽에 로깅할 수 잇음
    • 액션이 디스패치 됬을 때 이를 수정해서 리듀서에게 전달되도록 할 수 있음
    • 특정 액션이 발생했을 때 이에 기반하여 다른 액션이 발생되도록 할 수 있음
    • 특정 액션이 발생했을 때 특정 자바스크립트 함수를 실행시킬 수 있음
  • 유용한 함수와 Hooks를 사용할 수 있음

  • 글로벌 관리
    ContextAPI처럼 매번 context를 새롭게 만들 필요 없이 모든 글로벌 상태를 하나의 객체로 묶어서 사용하는 것이 필수임, 그래서 편리함

  • 설치

    yarn add react-redux
    

리덕스 키워드

  • 액션(action) 상태에 변화가 필요할 때 사용되며 객체 형태로 구성됨

    {
        type: '필수로 있어야됨',
        data: {
            id: 1,
            text: '기타값'
        }
    }
    
  • 액션 생성함수(Action Creator) 파라미터를 받아와서 액션 객체로 만들어주는 함수

    export function sample(data) {
      return { type: "SAMPLE_DATR", data };
    }
    
    // 화살표 함수형
    export const sample = (data) => ({
      type: "SAMPLED_DATA",
      data,
    });
    
  • 리듀서(Reducer) 변화를 일으키는 함수로써 파라미터를 두개 받아옴
    액션 타입이 무엇이냐에 따라 상태를 업데이트함
    불변성을 꼭 유지해줘야함
    default에서는 아래 예시 state처럼 기존 상태를 돌려주는 것이 원칙

    function coutner(state, action) {
      switch (action.type) {
        case "INCREASE":
          return state + 1;
        case "DECEREASE":
          return state - 1;
        default:
          return state;
      }
    }
    
  • 스토어(Store) 한 애플리케이션 당 하나의 스토어를 만들게됨 스토어 안에는 현재 앱에 상태와 리듀서가 들어있고 내장함수들이 들어있음

    // index.js
    
    // 스토어를 만들어주는 함수
    import { createStore } from "redus";
    
    // 스토어 생성
    const store = createStore(rootReducer);
    
    // Provider 적용
    ReactDom.render(
      <Provider store={store}>
        <App />
      </Provider>
    );
    
    • 디스패치(dispatch)
      액션을 발생시키는 것
      액션을 스토어에게 전달하는 것

      dispatch({ type: "INCREASE" });
      
    • 구독(subscribe)
      호출시 파라미터로 특정 함수를 넣어주면 액션이 디스패치 될때마다 설정한 함수가 호출됨

규칙

  1. 하나의 애플리케이션엔 하나의 스토어가 있음
  2. 상태는 읽기전용(불변성을 지켜줘야함) 불변성을 유지시켜줘야하는 이유는 리덕스에서 내부적으로 데이터가 변경 되는 것을 감지하기 위해 겉핥기식 검사를 하기 때문임
    덕분에 좋은 성능을 유지할 순 있음
  3. 변화를 일으키는 함수 리듀서는 순수한 함수여야 함
    • 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받음
    • 이전의 상태는 절대로 건들이지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환함
    • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 동일한 아웃풋이 있어야함
      (동일한 인풋 => 동일한 아웃풋)

리덕스 모듈

  • 액션 타입
  • 액션 생성 함수
  • 리듀서

위 항목들을 각각 다른 파일에 저장해서 사용할 수 있으며 하나의 파일에 몰아서 작성하는 방식을 Ducks 패턴이라고 함

  • 루트 리듀서 만들어 놓은 리덕스 모듈을 하나의 리듀서로 합쳐서 사용하는데 이때 합쳐진 리듀서를 루트 리듀서라고 부름

    // 루트 리듀서 함수
    import { combineReducers } from "redux";
    

리덕스 패턴

  • 프리젠테이셔널 컴포넌트

    리덕스 스토어에 직접적으로 접근하지 않고 필요한 값 또는 함수를 props로만 받아와서 사용하는 컴포넌트로써 주로 UI를 선언하는데 집중

  • 컨테이너 컴포넌트

    리덕스 스토어의 상태를 조회하거나, 액션을 디스패치 할 수 있는 컴포넌트

개발자도구(redux-devtools)

아래와 같은 작업 가능

현재 스토어의 상태를 개발자 도구에서 조회할 수 있음
지금까지 어떤 액션들이 디스패치되었는지 확인 가능
액션에 따라 상태가 어떻게 변화했는지 확인 가능
액션을 직접 디스패치 가능

  • 설치 크롬 웹스토어에서 redux-devtools설치

    프로젝트에서 redux-devtools-extension설치

    yarn add redux-devtools-extension
    
  • 적용

    // index.js
    import { composeWithDevTools } from "redux-devtools-extension";
    
    const store = createStore(rootReducer, composeWithDevTools());
    

useSelector

useSelector란 리덕스의 상태값을 조회하기 위한 Hook함수

  • 사용법

    // counterValue에 count 값 가져옴
    const count = useSelector(state => state.counterValue.count);
    
    // 여러 값 한번에 가져오기
    count {counter, person} = useSelector(state => ({
      count: state.counterValue.count,
      person: state.personValue.person
    }));