Redux
는 JavaScript 애플리케이션 상태 관리 라이브러리 중 하나로 Redux
공식문서에서는 "Redux는 여러분이 일관적으로 동작하고, 서로 다른 환경(서버, 클라이언트, 네이티브)에서 작동하고, 테스트하기 쉬운 앱을 작성하도록 도와줍니다."라고 설명하고 있다.
좀 더 자세히 설명하자면, 대부분의 애플리케이션은 상태(state
)를 가지고 있다.(ex. 로그인 정보, 사용자 프로필, 애플리케이션 설정 등) 이러한 상태는 보통 여러 컴포넌트에서 공유되거나 사용되기 때문에 상태를 중앙 집중적으로 관리할 필요가 있다.
Redux
는 이러한 중앙 집중적인 상태 관리를 위한 라이브러리로 상태를 객체 형태로 저장하며, 액션(action)을 통해 상태를 변경하고 리덕스 스토어(store)에서 이러한 액션을 처리한다.
Redux
는 상태의 변경을 예측 가능하게 만들어주는데, 이는 액션과 상태의 변경을 엄격하게 제어함으로써 가능하다. 또한, 리덕스는 액션을 로깅하거나 디버깅 도구를 사용하여 애플리케이션의 상태를 추적할 수 있다.
이처럼 Redux
를 사용하면 상태 관리를 중앙 집중적으로 처리할 수 있으며, 이는 애플리케이션의 복잡도를 낮추고 유지보수를 쉽게 만들어준다. 따라서 리액트 등의 프론트엔드 프레임워크와 함께 사용되며, 현재 많은 프로젝트에서 리덕스를 사용하고 있다.
그렇다면 이미 리덕스와 비슷한 리액트 내 Hook인 리액트 컨텍스트가 있는데 왜 리덕스가 필요할까?
리액트 컨텍스트 역시 prop 체인이나 prop 드릴링을 하지 않고, Context와 ContextProvider 컴포넌트를 중심으로 상태를 관리할 수 있다.
일단 둘의 차이를 한번 비교해 보자면 다음과 같다.
Context | Redux |
---|---|
React Components에서만 작동 | React Components 밖에서도 사용 가능 |
context 값 변경 시, consume하고 있는 component들이 모두 업데이트 (전체적으로 리렌더링) | action을 dispatch 하고 reducer로 업데이트 할수 있어 부분적으로 업데이트(리렌더링) |
side effect에 대한 메커니즘이 없음 | 미들웨어로 side effect를 관리 할 수 있음 |
소규모 애플리케이션 또는 간단한 값을 처리하기 유리 | 대규모 애플리케이션 같은 복잡한 로직에서 유리 |
Store
에 dispatch() 메서드를 통해 전달한다.
action
: 액션 type과 전송할 데이터(payload)로 이루어진 객체 형태store
: 애플리케이션의 상태를 저장하고 관리하는 객체dispatch는
: 액션값을 매개변수로, Reducer를 호출하는 것
store
는 액션 객체를 reducer
로 전달한다.
reducer
는 현재(이전)의 state
와 받은 action
에 따라 state
를 변화시킨 다음 새로운 state
객체를 반환한다.
reducer`는 상태를 변화시킬 때 이전 상태 객체의 값을 변경시키는 것이 아니라 새로운 객체를 반환하기 때문에 이전 상태 객체의 불변성을 지키며, 리덕스는 데이터가 변경되었다는 사실을 shallow equality checking 을 통해 알 수 있다.
shallow equality checking : 두 객체(a, b)를 단순히 a === b 인지만 체크하는 것
deep equality checking : 두 객체(a, b) 내부 프로퍼티까지 모두 같은지 일일이 체크를 하는 것
store
는 reducer
에서 반환된 새로운 상태 객체를 적용하며 이 과정에서, 기존 상태 객체와 새로운 상태 객체를 병합하거나 대체한다.
상태가 변경되면, store
는 이를 구독하는 컴포넌트들에게 새로운 상태가 적용되었음을 알리기 위해 알림을 보낸다. 이를 통해 컴포넌트는 새로운 상태를 반영하도록 업데이트한다.
Redux에서 상태를 더욱 쉽게 관리하고 구조화하는 데 도움을 주는 패키지로 Redux를 사용할 때 자주 사용되는 패턴과 기능을 쉽게 구현할 수 있도록 도와준다.