리덕스
이번 챕터에서 알아볼 주제는 리덕스(Redux) 입니다. 리덕스는 리액트 생태계에서 가장 사용률이 높은 상태관리 라이브러리입니다. 리덕스를 사용하면 여러분이 만들게 될 컴포넌트들의 상태 관련 로직들을 다른 파일들로 분리시켜서 더욱 효율적으로 관리 할 수 있으며 글로벌 상태 관리도 손쉽게 할 수 있습니다. 우리가 이전에 배운 Context API 를 사용해도 글로벌 상태 관리를 할 수 있고 상태 관리 로직을 분리 할 수 있습니다. 특히, Context API 와 useReducer
Hook 을 사용해서 개발하는 흐름은 리덕스를 사용하는 것과 매우 개발 방식이 유사합니다. 리덕스에서도 리듀서와 액션이라는 개념을 사용하거든요.
Redux는 Context API 가 지금의 형태로 사용방식이 개선되기도 전에, 그리고 useReducer
라는 Hook 이 존재하기도 전 부터 만들어진 라이브러리입니다. 사실 Context API 가 개선되기 전에는 프로젝트에서 글로벌 상태관리를 하는게 굉장히 까다로웠어요. 그래서 리덕스가 글로벌 상태 관리 용도로 많이 사용되어 왔었습니다.
npmtrends 를 통해 알 수 있는 사실은, 리액트를 사용하는 프로젝트 중 45%가 리덕스를 사용하고 있다는 것 입니다.
참고로 redux 는 리액트에서 사용하기 위해 만들어진 라이브러리이긴 하지만 무조건 리액트와 함께 사용 할 필요는 없습니다. 일반 JavaScript 환경에서 사용 할 수도 있고 Angular 와 같은 다른 프레임워크에서도 사용되기도 합니다. 이러한 이유 때문에 위 이미지를 보면 react-redux 보다 redux 의 다운로드 수치가 훨씬 높은 것 입니다.
그런데 리덕스에 대해서 배워보기 전에 한가지를 확실히 해 둘 것이 있습니다. 저렇게 많이 사용된다고 해서 여러분의 프로젝트에 리덕스가 무조건 필요하지는 않습니다. 물론, 잘 활용하면 상황에 따라 그리고 여러분의 취향에 따라 프로젝트 개발 생산성에 아주 큰 도움을 줄 수도 있습니다. 하지만 단순히 글로벌 상태 관리를 위한 것이라면 Context API를 활용하는 것 만으로 충분 할 수 있습니다.
리덕스를 사용하는 것 과 Context API를 사용하는 것의 차이
그렇다면 리덕스를 사용하는 것 과 Context API를 사용하는 것은 어떠한 차이가 있을까요?
1. 미들웨어
리덕스에는 미들웨어(Middleware)라는 개념이 존재합니다. 리덕스로 상태 관리를 할 때에는 우리가 useReducer
를 사용해볼때 접했던 개념인 리듀서 함수를 사용합니다. 리덕스의 미들웨어를 사용하면 액션 객체가 리듀서에서 처리되기 전에 우리가 원하는 작업들을 수행 할 수 있습니다. 예를 들자면..
- 특정 조건에 따라 액션이 무시되게 만들 수 있습니다.
- 액션을 콘솔에 출력하거나, 서버쪽에 로깅을 할 수 있습니다.
- 액션이 디스패치 됐을 때 이를 수정해서 리듀서에게 전달되도록 할 수 있습니다.
- 특정 액션이 발생했을 때 이에 기반하여 다른 액션이 발생되도록 할 수 있습니다.
- 특정 액션이 발생했을 때 특정 자바스크립트 함수를 실행시킬 수 있습니다.
미들웨어는 주로 비동기 작업을 처리 할 때 많이 사용됩니다.
useReducer
Hook 에서도 외부 라이브러리를 사용하면 미들웨어를 사용 할 수도 있습니다. 다만, 자주 사용되는 방식은 아닙니다.
2. 유용한 함수와, Hooks
우리가 이전에 Context API 와 useReducer
를 사용 할 때에는 Context 도 새로 만들고, Context 의 Provider 설정도 하고 각 Context 를 편하게 사용하기 위해 전용 커스텀 Hook 을 따로 만들어서 사용하기도 했는데요, 리덕스에서는 이와 비슷한 작업을 편리하게 해줄 수 있는 여러 기능들이 존재합니다.
connect
함수를 사용하면 리덕스의 상태 또는 액션 생성 함수를 컴포넌트의 props 로 받아올 수 있으며, useSelector
, useDispatch
, useStore
과 같은 Hooks를 사용하면 손쉽게 상태를 조회하거나 액션을 디스패치 할 수도 있죠.
connect
함수와 useSelector
함수에는 내부적으로 최적화가 잘 이루어져있어서 실제 상태가 바뀔때만 컴포넌트가 리렌더링됩니다. 반면에 Context API를 사용할 때에는 그러한 최적화가 자동으로 이루어져있지 않기 때문에 Context 가 지니고 있는 상태가 바뀌면 해당 Context 의 Provider 내부 컴포넌트들이 모두 리렌더링 되지요.
3. 하나의 커다란 상태
Context API 를 사용해서 글로벌 상태를 관리 할 때에는 일반적으로 기능별로 Context를 만들어서 사용하는 것이 일반적입니다 (물론 꼭 그렇게 할 필요는 없습니다). 반면 리덕스에서는 모든 글로벌 상태를 하나의 커다란 상태 객체에 넣어서 사용하는 것이 필수입니다. 때문에 매번 Context를 새로 만드는 수고로움을 덜 수 있습니다.
리덕스 언제 써야 할까?
리덕스를 여러분의 프로젝트에 써야 할지 말지 고민 할 때에는 다음 사항들을 고려해보세요.
프로젝트의 규모가 큰가?
- Yes: 리덕스
- No: Context API
비동기 작업을 자주 하게 되는가?
- Yes: 리덕스
- No: Context API
- 리덕스를 배워보니까 사용하는게 편한가?
- Yes: 리덕스
- No: Context API 또는 MobX
여기서 3번, 매우 중요합니다. 아무리 리덕스가 좋은 라이브러리라 해도 여러분의 취향에 맞지 않고 어렵게만 느껴지고 맘에 들지 않는다면 사용하지 않는 것이 좋습니다. 그런데 3번에 대한 결정을 내리려면 일단 배워볼 필요는 있겠죠? 그럼, 배워봅시다!