리덕스를 써야 할 때 & 리덕스의 장단점 (feat. 공식문서)

Sheryl Yun·2023년 5월 12일
4

전역 상태 관리

목록 보기
2/2
post-thumbnail

Redux란

  • 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너
  • 매우 가벼움 (의존 라이브러리 포함 2kB)
  • React 외에도 다른 뷰 라이브러리와 함께 사용 가능

어떤 문제를 해결하는 데 도움이 되나요?

  • "액션"이라는 이벤트를 사용하여 애플리케이션 상태를 관리하고 업데이트하는 패턴 또는 라이브러리

  • 상태가 예측 가능한 방식으로만 업데이트될 수 있도록 하는 규칙 보유

  • 전체 애플리케이션에서 사용해야 하는 상태에 대한 중앙 집중식 저장소 역할
    (= 애플리케이션의 여러 부분에서 필요한 "전역 상태" 관리)

  • 애플리케이션의 상태가 언제, 어디서, 왜, 어떻게 업데이트되는지, 이러한 변경이 발생할 때 애플리케이션 로직이 어떻게 작동하는지 더 쉽게 이해 가능

  • 예측 가능하고 테스트 가능한 코드를 작성하도록 유도
    -> 애플리케이션이 예상대로 작동할 것이라는 확신을 준다

Redux Toolkit (= RTK)

  • Redux 로직을 작성하기 위해 공식적으로 추천되는 방법
  • 대부분의 Redux 작업을 단순화하고 실수를 방지
  • Redux 앱을 더 만들기 쉽게 해주는 유틸리티 포함
    => store 준비, reducer 생성, 불변 수정 로직 작성, 상태 "조각(slice)"을 한 번에 작성 등

Redux 기본 원리

앱의 상태를 하나의 저장소(store)안에 있는 객체 상태 트리에 저장

  • 상태 트리를 변경하는 유일한 방법
    무엇이 일어날지 서술하는 객체인 액션(action)을 보내는 것뿐
  • 리듀서(reducers)
    • 액션이 상태 트리를 어떻게 변경할지 명시하는 함수
    • (state, action) => state 형태의 순수 함수

위의 규칙과 함수가 있는 이유:
상태가 바뀌었을 때 상태 객체를 변경하지 않고 새로운 객체를 반환하도록 하기 위해

코드 구조

  1. store 생성 함수 임포트 (createStore)
  2. 액션이 전체 애플리케이션의 상태를 어떻게 변경할지 결정하는 리듀서 함수 작성
  3. 앱의 상태를 보관하는 store 생성
    • store가 갖고 있는 API: subscribe, dispatch, getState
  4. 상태를 store에 구독(subscribe)
    • subscribe()를 이용하여 상태 변화에 따라 UI가 변경되게 하는데,
      보통은 subscribe()를 직접 사용하기보다 뷰 바인딩 라이브러리(예: react-redux) 사용
  5. dispatch로 액션을 보냄
    • 상태를 바로 변경하는 대신 액션이라 불리는 객체를 통해 일어날 변경을 명시
    • store의 내부 상태를 변경하는 유일한 방법은 액션을 보내는 것뿐
    • 액션은 직렬화/로깅/저장 또는 나중에 재실행 가능

보통의 Redux 앱에는 하나의 'root 리듀서' 함수를 가진 단 하나의 저장소(store)가 있음
=> combineReducers()로 여러 리듀서 함수를 묶어 하나의 root 리듀서 함수를 완성할 수 있다

import { createStore } from 'redux';

function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

let store = createStore(counter)

store.subscribe(() => console.log(store.getState())))

store.dispatch({ type: 'INCREMENT' }); // 1
store.dispatch({ type: 'INCREMENT' }); // 2
store.dispatch({ type: 'DECREMENT' }); // 1

Redux의 장점과 단점

Redux는 공유 상태 관리를 처리하는 데 도움이 되지만 다른 도구와 마찬가지로 장단점이 있다.

장점 🎉

  • 크고 복잡한 앱에서 확장성이 높음
  • 액션에 따른 모든 변경을 추적 가능
  • "특정 상태 조각이 언제 변경되었으며 데이터는 어디에서 왔는지" 동작을 예측 가능
  • 강력한 개발자 도구
    • 예: 사용자 세션을 기록한 다음 액션 하나하나를 다시 실행해본다

단점 🎃

  • 코드를 작성하는 가장 짧거나 빠른 방법은 아님
  • 배워야 할 개념과 작성해야 할 코드가 많음

Redux의 창시자 중 한 명인 Dan Abramov 🧔
"바닐라 React에 문제가 생길 때까지 Redux를 사용하지 마십시오"

Redux가 유용한 경우

  • 앱의 여러 위치에서 필요한 상태의 양이 많을 때
  • 시간이 지남에 따라 상태가 자주 업데이트될 때
  • 큰 규모의 코드베이스를 가지고 많은 사람들이 작업할 때
  • 시간이 지남에 따라 상태가 어떻게 업데이트되는지 확인해야 할 때

즉, 모든 앱에 Redux가 필요한 것은 아니다.

출처: Redux에 도달해야 하는 경우와 그렇지 않은 경우 📢

특정 도구를 선택할 때는

다른 사람이 사용해야 한다고 해서, 또는 인기가 많아서가 아니라
지금 이것이 나에게 가장 잘 맞는 도구이기 때문에 선택해야

리덕스와 Context API 비교

Context의 유일한 목적은
하위 트리의 일부로 범위가 지정된 종속성 주입 메커니즘으로 작동하는 것

  • "여기에 값이 있습니다"라고 말하면 해당 구성 요소 하위 트리의 모든 부분에서 값 읽기를 요청 가능 (말 그대로 그게 다임)

  • 따라서, Redux로 해야 할 유일한 일이 여러 구성 요소를 통해 데이터를 props로 전달하는 것(= props drilling)을 피하는 것이라면 Redux를 추가할 필요가 없고 대신 Context 사용하기

사람들은 끊임없이 비교한다. 🤔🙄
"컨텍스트를 사용해야 하나, 아니면 Redux를 사용해야 하나?"
그들은 Context 자체가 '상태 관리 시스템'이라고 생각하는 것 같다. 그렇지 않다.
Context는 종속성 주입 메커니즘이며, 컨텍스트에 원하는 값을 무엇이든 넣을 수 있고 대부분의 경우 hook을 사용하여 해당 상태를 관리한다.
즉, Redux가 React로 하는 것과 비슷하지만 Context 자체는 상태 관리 시스템이 아니다.

리덕스와 서버 상태 캐시 라이브러리

Redux로 수행한 유일한 작업이 서버의 캐시 데이터를 저장하는 것이라면 그 상황에서는 Redux가 필요하지 않다.

GraphQL, Apollo 클라이언트, SWR, React Query 등 그 일을 더 잘 하는 라이브러리가 많다.

위 작업이 Redux로 계획한 유일한 일이라면 그 시점에서는 Redux가 필요하지 않다.

그럼 언제 리덕스를 써야 하나요?

Redux는 광범위한 사용 사례에 사용 가능
매우 '일반적'인 상태 관리 도구이다.

  • 서버에서 캐싱 상태
  • UI 상태
  • 클라이언트에서 기타 복잡한 데이터 관리 등

그러나 이러한 모든 사용 사례에서 가장 우수하거나 가장 효율적인 도구는 아니다.

예를 들어 React Query 또는 Apollo와 같은 다른 도구가 이러한 특정 데이터 가져오기 사례에 훨씬 더 특화되어 있다.

Redux를 사용하고자 한다면 다음의 질문을 꼭 해보자.

  1. 어떤 구체적인 문제를 해결하려고 하는지
  2. 이 도구는 어떤 문제를 해결하는지
  3. 그 사이에 중복되는 범위는 어디인지

=> 즉, 이 라이브러리가 이 문제를 해결하기에 충분한지를 반드시 고려

글을 읽고 내린 결론 👱‍♀️

도구를 사용하기 전

  • 지금 내가 해결하려는 문제를 구체적으로 먼저 정의 (무엇을 해결하려고 하는가?)
  • 이 문제를 해결하기 위해 (리덕스도 사용할 수 있지만) 더 잘 해결할 수 있는 도구가 있는지 생각하기
  • 이후에도 리덕스가 해결해야 할 범위가 더 넓다고 생각되면 그 때 리덕스 사용
profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글