본문으로 건너뛰기
비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

기본 리듀서 구조와 상태 형태

기본 리듀서 구조

가장 먼저 이해해야 할 점은, 전체 애플리케이션에는 사실상 하나의 리듀서 함수만 존재한다는 것입니다. 이는 createStore의 첫 번째 인수로 전달한 함수를 말합니다. 이 단일 리듀서 함수는 궁극적으로 다음 작업들을 수행해야 합니다:

  • 리듀서가 처음 호출될 때 state 값은 undefined입니다. 리듀서는 들어오는 액션을 처리하기 전에 기본 상태 값을 제공하여 이 경우를 처리해야 합니다.

  • 이전 상태와 디스패치된 액션을 확인하고, 어떤 종류의 작업이 필요한지 결정해야 합니다.

  • 실제 변경이 필요한 경우, 업데이트된 데이터로 새로운 객체와 배열을 생성하여 반환해야 합니다.

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

리듀서 로직을 작성하는 가장 간단한 방법은 모든 내용을 단일 함수 선언에 포함시키는 것입니다. 예를 들면 다음과 같습니다:

function counter(state, action) {
if (typeof state === 'undefined') {
state = 0 // If state is undefined, initialize it with a default value
}

if (action.type === 'INCREMENT') {
return state + 1
} else if (action.type === 'DECREMENT') {
return state - 1
} else {
return state // In case an action is passed in we don't understand
}
}

이 간단한 함수가 모든 기본 요구사항을 충족함에 주목하세요. 존재하지 않을 경우 기본값을 반환하여 스토어를 초기화하고, 액션 유형을 기반으로 어떤 업데이트가 필요한지 결정한 후 새 값을 반환하며, 작업이 필요 없을 때는 이전 상태를 반환합니다.

이 리듀서에 적용할 수 있는 몇 가지 간단한 개선점이 있습니다. 첫째, 반복되는 if/else 문은 금방 번거로워지므로 switch 문을 사용하는 것이 일반적입니다. 둘째, 초기 "기존 데이터 없음" 사례를 처리하기 위해 기본 매개변수 값을 사용할 수 있습니다. 이러한 변경을 적용하면 리듀서는 다음과 같이 됩니다:

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

이것이 일반적인 Redux 리듀서 함수의 기본 구조입니다.

기본 상태 형태

Redux는 관리해야 할 데이터 측면에서 애플리케이션을 생각하도록 권장합니다. 특정 시점의 데이터는 애플리케이션의 "상태"이며, 이 상태의 구조와 조직화는 일반적으로 "형태"라고 부릅니다. 상태 형태는 리듀서 로직을 구조화하는 방식에 큰 영향을 미칩니다.

Redux 상태는 일반적으로 상태 트리의 최상위에 일반 JavaScript 객체를 가집니다. (단일 숫자, 배열 또는 특수화된 데이터 구조와 같은 다른 유형의 데이터를 사용할 수도 있지만, 대부분의 라이브러리는 최상위 값이 일반 객체라고 가정합니다.) 이 최상위 객체 내에서 데이터를 구성하는 가장 일반적인 방법은 데이터를 하위 트리로 추가 분할하는 것입니다. 각 최상위 키는 관련 데이터의 특정 "도메인" 또는 "슬라이스"를 나타냅니다. 예를 들어, 기본 Todo 앱의 상태는 다음과 같을 수 있습니다:

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

이 예시에서 todosvisibilityFilter는 모두 상태의 최상위 키이며, 각각 특정 개념에 대한 데이터 "슬라이스"를 나타냅니다.

대부분의 애플리케이션은 크게 세 가지 범주로 나눌 수 있는 여러 유형의 데이터를 다룹니다:

  • 도메인 데이터: 애플리케이션이 표시, 사용 또는 수정해야 하는 데이터 (예: "서버에서 가져온 모든 Todos")

  • 애플리케이션 상태: 애플리케이션 동작과 관련된 데이터 (예: "Todo #5가 현재 선택됨" 또는 "Todos를 가져오기 위한 요청 진행 중")

  • UI 상태: UI가 현재 어떻게 표시되는지를 나타내는 데이터 (예: "EditTodo 모달 대화상자가 현재 열림")

스토어는 애플리케이션의 핵심을 나타내므로, 상태 형태를 UI 컴포넌트 트리가 아닌 도메인 데이터와 애플리케이션 상태 측면에서 정의해야 합니다. 예를 들어, state.leftPane.todoList.todos 형태는 좋지 않은 방법입니다. "todos" 개념은 UI의 일부가 아닌 전체 애플리케이션의 중심이기 때문입니다. todos 슬라이스는 상태 트리의 최상위에 위치해야 합니다.

UI 트리와 상태 구조 사이에 일대일 대응 관계가 있는 경우는 _드물_습니다. Redux 스토어에서 UI 데이터의 다양한 측면을 명시적으로 추적하는 경우가 예외가 될 수 있지만, 그런 경우에도 UI 데이터의 구조와 도메인 데이터의 구조는 서로 다를 가능성이 높습니다.

일반적인 애플리케이션의 상태 구조는 대략 다음과 같을 수 있습니다:

{
domainData1 : {},
domainData2 : {},
appState1 : {},
appState2 : {},
ui : {
uiState1 : {},
uiState2 : {},
}
}