이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →
선행 기술
Redux는 다양한 유산을 지니고 있습니다. 일부 패턴 및 기술과 유사하지만 중요한 점에서 차이를 보이기도 합니다. 아래에서 몇 가지 유사점과 차이점을 살펴보겠습니다.
개발자 경험
Dan Abramov(Redux 창시자)는 “핫 리로딩과 타임 트래블”이라는 React Europe 발표를 준비하며 Redux를 개발했습니다. 그의 목표는 최소한의 API로 완전히 예측 가능한 동작을 제공하는 상태 관리 라이브러리를 만드는 것이었습니다. Redux는 로깅, 핫 리로딩, 타임 트래블, 유니버설 앱, 기록 및 재생을 개발자의 추가 작업 없이 구현할 수 있게 합니다.
Dan은 Changelog 에피소드 187에서 자신의 의도와 접근 방식 일부를 설명했습니다.
영향 요소
Redux는 Flux의 아이디어를 발전시켰지만, Elm에서 영감을 얻어 복잡성을 피했습니다. Flux나 Elm을 사용해 본 적이 없더라도 Redux는 몇 분 안에 시작할 수 있습니다.
Flux
Redux는 Flux의 중요한 특성들에서 영감을 받았습니다. Flux처럼 Redux는 모델 업데이트 로직을 애플리케이션의 특정 계층(Flux에서는 "stores", Redux에서는 "reducers")에 집중하도록 합니다. 애플리케이션 코드가 데이터를 직접 변이하게 하는 대신, 두 방식 모두 모든 변경을 "action"이라는 평범한 객체로 기술하도록 합니다.
Flux와 달리 Redux는 Dispatcher 개념이 없습니다. 이는 Redux가 이벤트 이미터 대신 순수 함수에 의존하기 때문이며, 순수 함수는 구성하기 쉽고 추가 관리 주체가 필요하지 않습니다. 관점에 따라 이는 변형이나 구현 세부사항으로 볼 수 있습니다. Flux는 종종 (state, action) => state로 설명됩니다. 이런 의미에서 Redux는 Flux 아키텍처에 충실하되 순수 함수 덕분에 더 단순해졌습니다.
Flux와의 또 다른 중요한 차이는 Redux가 데이터 변이를 허용하지 않는다는 점입니다. 상태로 평범한 객체와 배열을 사용해도 좋지만, 리듀서 내부에서 이를 변이하는 것은 강력히 권장하지 않습니다. 항상 새로운 객체를 반환해야 하며, 이는 객체 전개 연산자나 Immer 불변성 업데이트 라이브러리로 구현할 수 있습니다.
성능 극한 상황에서 데이터를 변이하는 불순한 리듀서 작성이 기술적으로 가능하긴 하지만, 이를 적극적으로 권장하지 않습니다. 타임 트래블, 기록/재생, 핫 리로딩 같은 개발 기능이 동작하지 않을 것입니다. 게다가 대부분의 실제 앱에서 불변성은 성능 문제를 유발하지 않습니다. Om이 증명하듯, 객체 할당 비용이 발생하더라도 리듀서 순수성으로 정확한 변경 사항을 알 수 있어 비싼 재렌더링과 재계산을 피할 수 있기 때문입니다.
Elm
Elm은 Haskell에서 영감을 받은 함수형 프로그래밍 언어로, Evan Czaplicki가 만들었습니다. Elm은 업데이트 시그니처가 (action, state) => state인 "모델 뷰 업데이트" 아키텍처를 적용합니다. Elm의 "업데이터"는 Redux의 리듀서와 동일한 역할을 합니다.
Redux와 달리 Elm은 언어이기 때문에 강제된 순수성, 정적 타이핑, 즉시 사용 가능한 불변성, case 표현식을 통한 패턴 매칭 등 다양한 이점을 활용할 수 있습니다. Elm을 사용할 계획이 없더라도 Elm 아키텍처에 대해 학습하고 직접 실험해 볼 것을 권장합니다. 유사한 개념을 구현한 흥미로운 JavaScript 라이브러리 플레이그라운드가 존재합니다. Redux에 영감을 얻기 위해 이 프로젝트를 살펴볼 가치가 있습니다! Elm의 정적 타이핑에 가까워질 수 있는 한 가지 방법은 Flow 같은 점진적 타이핑 솔루션을 도입하는 것입니다.
Immutable
Immutable은 영구 데이터 구조를 구현한 JavaScript 라이브러리로, 뛰어난 성능과 JavaScript 관용적 API를 제공합니다.
(Immutable.js가 Redux 개발에 영감을 주었지만, 현재는 불변 업데이트 작성 시 Immer 사용을 권장합니다.)
Redux는 상태 저장 방식에 제약을 두지 않습니다—일반 객체, Immutable 객체, 기타 자료구조 모두 사용 가능합니다. 유니버설 앱 개발이나 서버에서 상태를 불러올 때 (역)직렬화 메커니즘이 필요할 수 있지만, 이외에는 불변성을 지원하는 모든 데이터 저장 라이브러리를 활용할 수 있습니다. 예를 들어 Backbone 모델은 가변(mutable)이므로 Redux 상태 관리에 적합하지 않습니다.
불변 라이브러리가 커서(cursors)를 지원하더라도 Redux 애플리케이션에서는 사용하지 않아야 합니다. 전체 상태 트리는 읽기 전용으로 간주하며, 상태 업데이트와 변경 구독에는 반드시 Redux를 사용해야 합니다. 따라서 커서를 통한 직접 수정은 Redux 패러다임과 맞지 않습니다. 상태 트리와 UI 트리의 분리나 커서 세분화가 주요 사용 사례라면 셀렉터(selectors)를 고려하세요. 셀렉터는 조합 가능한 게터(getter) 함수입니다. 우아하게 구현된 셀렉터 구성 사례는 reselect를 참조하십시오.
Baobab
Baobab은 일반 JavaScript 객체에 불변 API를 적용한 또 다른 인기 라이브러리입니다. Redux와 함께 사용할 수 있으나 시너지 효과는 미미합니다.
Baobab의 핵심 기능은 커서 기반 데이터 업데이트에 있지만, Redux는 액션 디스패치를 통한 업데이트를 강제합니다. 두 라이브러리는 동일한 문제를 서로 다른 방식으로 해결하므로 상호 보완적이지 않습니다.
Immutable과 달리 Baobab은 내부적으로 고성능 자료구조를 구현하지 않아 Redux 연동 시 특별한 이점이 없습니다. 이 경우 일반 객체를 직접 사용하는 것이 더 실용적입니다.
RxJS
RxJS는 비동기 애플리케이션의 복잡성을 관리하는 탁월한 도구입니다. 실제로 인간-컴퓨터 상호작용을 상호의존적 옵저버블로 모델링하는 라이브러리 개발 사례도 존재합니다.
Redux와 RxJS를 함께 사용하는 것이 의미 있을까요? 물론입니다! 두 기술은 훌륭하게 조화됩니다. 예를 들어 Redux 스토어를 옵저버블로 노출하는 것은 간단합니다:
function toObservable(store) {
return {
subscribe({ next }) {
const unsubscribe = store.subscribe(() => next(store.getState()))
next(store.getState())
return { unsubscribe }
}
}
}
마찬가지로 다양한 비동기 스트림을 조합하여 store.dispatch()로 전달하기 전에 액션으로 변환할 수 있습니다.
핵심 질문은: Rx를 이미 사용 중이라면 Redux가 정말 필요한가? 입니다. Rx로 Redux 재구현은 어렵지 않습니다. 어떤 개발자들은 Rx의 .scan() 메서드로 단 두 줄 구현이 가능하다고 주장하기도 합니다. 실제로 가능할 것입니다!
의문이 있다면 Redux 소스 코드(내용이 많지 않음)와 생태계(예: 개발자 도구)를 확인해 보세요. 관심이 적고 반응형 데이터 흐름을 완전히 따르고 싶다면 Cycle 같은 대안을 탐색하거나 Redux와 결합해 볼 수도 있습니다. 결과를 알려주시기 바랍니다!
추천사
“Redux로 구현하는 방식이 정말 마음에 들어요” 플럭스(Flux) 창시자 징 첸(Jing Chen)
“페이스북 내부 JS 토론 그룹에서 Redux에 대한 의견을 물었는데, 만장일치로 극찬받았습니다. 정말 놀라운 작품이에요.” 플럭스 문서 작성자 빌 피셔(Bill Fisher)
“플럭스를 전혀 사용하지 않으면서 더 나은 플럭스를 만든다는 점이 정말 멋집니다.” 사이클(Cycle) 창시자 안드레 스탈츠(André Staltz)
감사의 말
-
리듀서로 상태 업데이트를 모델링하는 데 훌륭한 입문서가 되어준 The Elm Architecture;
-
사고를 확장시켜 준 Turning the database inside-out;
-
재평가가 "그냥 작동해야 한다"는 확신을 심어준 Developing ClojureScript with Figwheel;
-
핫 모듈 교체(Hot Module Replacement)를 가능하게 한 Webpack;
-
보일러플레이트나 싱글톤 없이 플럭스에 접근하는 법을 가르쳐 준 Flummox;
-
핫 리로드 가능 스토어 개념을 검증해 준 disto;
-
이 아키텍처가 성능을 보장할 수 있음을 입증한 NuclearJS;
-
단일 상태 원자(single state atom) 개념을 대중화한 Om;
-
함수가 종종 최고의 도구임을 보여준 Cycle;
-
실용적인 혁신을 선사한 React.
redux NPM 패키지 이름을 양도해 준 Jamie Paton에게 특별한 감사를 드립니다.
후원자
Redux 초기 작업은 커뮤니티의 후원으로 진행되었습니다. 이를 가능하게 해 준 주목할 만한 기업들을 소개합니다:
초기 Redux 후원자 전체 목록과 지속적으로 증가하는 Redux 사용 기업 및 개인 목록을 참고하세요.