Redux
  • Read Me
  • 소개
    • 동기
    • Core Concepts
    • 3가지 원칙
    • 기존 기술들
    • Learning Resources
    • 생태계
    • 예시
  • 기초
    • 액션
    • 리듀서
    • 스토어
    • 데이터 흐름
    • React와 함께 사용하기
    • 예시: Todo List
  • 심화
    • 비동기 액션
    • 비동기 흐름
    • 미들웨어
    • React Router와 함께 사용하기
    • 예시: Reddit API
    • Next Steps
  • 레시피
    • Configuring Your Store
    • Redux로 마이그레이션
    • 객체 확산 연산자 사용하기
    • 보일러플레이트 줄이기
    • Server Rendering
    • Writing Tests
    • Computing Derived Data
    • Implementing Undo History
    • Isolating Subapps
    • 리듀서 구조화하기
      • 사전에 요구되는 개념들
      • 기본 리듀서 구조
      • 리듀서 로직 분리하기
      • 리듀서 예제 리팩토링하기
      • combineReducers 사용하기
      • combineReducers 더 알아보기
      • 상태 정규화하기
      • 정규화된 데이터 업데이트하기
      • 리듀서 로직 재사용하기
      • 불변 업데이트 패턴
      • 상태 초기화하기
    • Using Immutable.JS with Redux
  • FAQ
    • General
    • Reducers
    • Organizing State
    • Store Setup
    • Actions
    • Immutable Data
    • Code Structure
    • Performance
    • Design Decisions
    • React Redux
    • Miscellaneous
  • 문제해결
  • 용어사전
  • API 레퍼런스
    • createStore
    • Store
    • combineReducers
    • applyMiddleware
    • bindActionCreators
    • compose
  • 변경 기록
  • 후원자
  • 피드백
Powered by GitBook
On this page
  • 기본 리듀서 구조
  • 기본적인 상태의 형태
  1. 레시피
  2. 리듀서 구조화하기

기본 리듀서 구조

기본 리듀서 구조

우선 우리 애플리케이션의 리듀서는 사실 createStore로 전달한 첫 번째 매개변수인 하나의 함수라는 것을 이해하는 것이 중요합니다. 이 하나의 리듀서는 궁극적으로 몇 가지 일을 해야합니다.

  • 리듀서가 처음 호출될 때, state값은 undefined가 됩니다. 초깃값을 지정해서 액션이 발생하기 전에 이 케이스에 대해 처리해줘야 합니다.

  • 이전의 상태와 전달된 액션을 통해 어떤 일을 해야 하는지를 결정해야 합니다.

  • 실제로 변경이 일어나면 업데이트된 데이터로 만들어져야 할 새로운 객체와 배열을 만들어 반환합니다.

  • 변경이 필요하지 않다면 기존 상태를 그대로 반환합니다.

가장 쉬운 접근은 아래와 같이 모든 리듀서 로직을 한가지 함수에 전부 넣는 것입니다.

function counter(state, action) {
  if (typeof state === 'undefined') {
    state = 0; // 상태가 undefined이면 기본값으로 초기화합니다.
  }

  if (action.type === 'INCREMENT') {
    return state + 1;
  } 
  else if (action.type === 'DECREMENT') {
    return state - 1;
  } 
  else {
    return state; // 정해놓지 않은 액션인 경우
  }
}

이 간단한 함수가 모든 필요사항을 충족함에 주목하세요. (액션이) 존재하지 않으면 기본값을 반환하고, 스토어를 초기화합니다; 액션의 종류에 따라 어떤 업데이트가 필요한지를 결정하고 새로운 값을 반환합니다; 또한 아무 일도 안 해도 된다면 이전의 상태를 반환합니다.

이 리듀서를 만들수 있는 간단한 방법이 있습니다. 첫째,if/else 는 빠르게 무거워지기 때문에 대신 switch문을 사용합니다. 둘째, "기존 데이터가 없는" 경우를 위해 ES6의 default parameter 문법을 사용합니다.

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

이것이 전형적인 리덕스 리듀서함수의 기본 구조입니다.

기본적인 상태의 형태

리덕스는 관리해야 할 데이터라는 측면에서 애플리케이션을 생각할 것을 권장합니다. 특정 시점의 데이터는 애플리케이션의 "상태"라고 하고 이 상태의 구조와 구성은 보통 "형태" 라고 합니다. 상태의 형태는 리듀서의 로직을 구성하는 데 중요한 역할을 합니다.

리덕스의 상태는 보통 상태 트리의 제일 꼭대기에 일반적인 자바스크립트 객체를 가지고 있습니다. (분명 숫자나 배열 혹은 다른 데이터구조를 가지는 것도 가능하지만 대부분의 라이브러리에서는 맨 꼭대기의 값이 객체라고 가정합니다) 꼭대기 객체의 데이터를 구성하는 일반적인 방법은 최상위의 키를 연관된 "도메인"이나 "조각"을 나타내는 서브 트리로 나누는 것입니다. 예를 들어 기본 Todo 앱의 상태는 다음과 같을 것입니다:

{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}

이 예제에서 todos와 visibilityFilter는 모두 상태의 최상위 키이며 각각 특정 개념에 대한 상태의 조각입니다.

보통 애플리케이션에서는 여러 데이터종류를 가지며, 크게 세가지 범주로 나뉩니다.

  • Domain data: 애플리케이션으로 보여주거나 사용, 수정할 데이터 (서버에서 가져온 모든 Todos와 같은 것들)

  • App state: 애플리케이션의 동작을 위한 특정 데이터 ("현재 Todo #5가 선택됨." 혹은 "Todos를 가져오는 요청이 있습니다."와 같은 것들)

  • UI_state: 현재 UI가 어떻게 보일 것인가에 대한 데이터 ("EditTodo Modal 상자가 현재 열려있음"과 같은 것들)

스토어는 애플리케이션의 핵심이기 때문에 반드시 상태는 UI 컴포넌트가 아닌 도메인데이터와 앱의 상태에 따라 구성해야 합니다. 예를 들어 state.leftPane.todoList.todos의 형태는 좋지 못합니다. "todos"는 그저 UI의 한 부분이 아니라 전체 애플리케이션의 중심이기 때문입니다.

드물게 UI트리와 상태 트리가 일대일대응인 경우가 있을 수 있습니다. 이 경우는 다양한 UI 데이터의 양상을 리덕스 스토어에서 추적하는 경우 일겁니다. 하지만 그때 역시 UI데이터와 도메인데이터의 모양은 다를겁니다.

전형적인 앱 상태의 형태는 대충 다음과 같을겁니다.

{
  domainData1 : {},
  domainData2 : {},
  appState1 : {},
  appState2 : {},
  ui : {
    uiState1 : {},
    uiState2 : {},
  }
}
Previous사전에 요구되는 개념들Next리듀서 로직 분리하기

Last updated 6 years ago