새소식

반응형
Study

React 상태관리 라이브러리 1탄 (Redux)

  • -
반응형

React 에는 많은 상태관리 라이브러리들이 있습니다. 그중에 가장 많이 사용하는 Redux를 먼저 정리해 보았습니다.

Redux의 역사

MVC 패턴

Redux의 역사는 MVC 패턴에서 시작합니다. MVC 패턴에서 Cotroller는 Model에 정의된 데이터를 조회하거나 업데이트하는 역할을 하고, 변경된 Model의 데이터를 View에 반영해 줍니다. 또한 사용자는 View를 통해 데이터를 입력하고 Model에 반영되며, View 와 Model은 데이터를 양방향으로 주고받는 형태입니다.

출처: Flux 공식문서

프로젝트의 규모가 커질수록 수많은 View와 Model들이 생겨났기 때문에 데이터가 어디로 흐르는지 파악하기 어렵다는 문제점이 있었습니다.

출처: Fulx 공식문서

새 기능을 추가할때 마다 크고 작은 문제가 생겼고, 예상 할 수 없는 결과(Side Effect)가 일어났습니다.

 

Flux의 시작

이러한 문제들을 해결하기 위해 페이스북 개발팀에서 새로운 아키텍처를 적용하기로 하여 나온것이 Flux 패턴입니다.

출처: Flux 공식문서

Flux 패턴은 어떤 Action이 발생하면 dispatcher에 의해 store에 변경된 사항이 저장되고 그 저장된 데이터들에 의해 view가 변경되는 단방향 패턴입니다. 이러한 패턴의 가장 큰 장점은 양방향으로 흐르던 MVC 패턴과 반대로 단방향으로 흐르기 때문에 흐름을 파악하기 쉽고 예측 가능하다는 것입니다.

 

이런 Flux 패턴을 적용한 구현체들이 많이 있는데 그 중 하나가 바로 Redux 입니다.

 

Redux의 핵심 키워드

Store
Store는 애플리케이션의 상태 트리를 가지고 있는 객체.
Redux 앱에는 단 하나의 저장소만 있어야 합니다.
State
State는 넓은 의미의 단어이지만, Redux API 에서는 보통 저장소에 의해 관리되고 getState()에 의해 반환되는 하나의 상태 값을 지칭. state는 Redux 애플리케이션의 전체 상태를 나타내며, 보통 깊게 중첩되어 있는 객체입니다.
Action
Action은 상태를 변화시키려는 의도를 표현하는 평범한 객체.
action으 store에 데이터를 넣는 유일한 방법입니다.
Action Creator
Action Creator는 단지 Action을 만드는 함수 입니다.
action creator를 호출하면 Action을 만들어낼 뿐 dispatch하지는 않습니다.
action creator를 호출해 그 결과를 Store인스턴스로 바로 dispatch하는 함수를 바인드된 액션 생성자 라고 부르기도 합니다. 
action creator가 현재 상태를 읽어야 하거나 API 호출을 실행하거나, 라우트 전환같은 부수효과를 일으켜야 한다면, action대신 asyncAction을 반환해야 합니다.
Reducer
Reducer는 누적값과 값을 받아서 새로운 누적값을 반환하는 함수.
이들은 값들의 컬렉션을 받아서 하나의 값을 줄이는데 사용됩니다. reducer는 Redux만의 개념은 아닙니다.
Redux에서 누적값은 상태 객체이고, 누적될 값은 액션입니다.
리듀서는 주어진 이전 상태와 액션에서 새로운 상태를 계산합니다.
=> 현재(이전)의 state와 action을 인자로 받아 store에 접근해 action에 맞춰 state를 변경 합니다.
이들은 반드시 같은 입력이 있으면 같은 출력을 반환하는 순수 함수 여야만 합니다.
Dispatch
Dispatch는 store의 내장 함수 중 하나로, action이나 async action을 받는 함수.
기본 dispatch 함수는 반드시 동기적으로 store에 reducer에 action을 보내야 합니다. 그러면 reducer는 Store가 반환한 이전 상태와 함께 새 상태를 계산합니다. reducer가 사용하기 위해서 action은 평범한 객체여야 합니다.
middleware는 기본 dispatch 함수를 감쌉니다. middleware를 통해 dispatch 함수는 action뿐만 아니라 async action을 처리 할 수 있습니다. middleware는 action이나 async action을 다음 middleware에 넘기기 전에 변환하거나, 지연시키거나, 무시하거나, 해석할 수 있습니다.
Async Action
Async Action은 dispatch로 보내지는 값이지만. 아직 reducer에게 받아들려질 준비가 되어 있지는 않았습니다. async action은 기본 dispatch함수로 전달되기 전에 middleware를 통해 action등으로 바뀌어야 합니다. async action은 여러분이 사용하는 middleware에 따라 서로 다른 타입이 될 수 있습니다.
Middleware
Middleware는 dispatch함수를 결합해서 새 dispatch함수를 반환하는 고차함수.
middleware는 함수 결합을 통해 서로 결합할 수 있습니다. 이는 action을 로깅하거나, 라우팅과 같은 부수효과를 일으키거나, 비동기 API 호툴을 일련의 동기 액션으로 바꾸는데 유용합니다.
Subscribe
Subscribe는 store의 내장 함수 중 하나로, 특정 함수를 전달해주면 action이 dispatch 되었을 때마다 전달된 함수가 호출 됩니다.

Redux의 세가지 원칙

1. Single source of truth

애플리케이션의 모든 상태는 하나의 저장소 안에 하나의 개체 트리 구조로 저장됩니다.

이를 통해 범용적인 애플리케이션(universal application, 하나의 코드 베이스로 다양한 환경에서 실행 가능한 코드)을 만들기 쉽게 만들 수 있습니다. 서버로부터 가져온 상태는 시리얼라이즈되거나(serialized) 수화되어(hydrated) 전달되며 클라이언트에서 추가적인 코딩 없이도 사용할 수 있습니다. 또한 하나의 상태 트리만을 가지고 있기 때문에 디버깅에도 용이할 것입니다. 빠른 개발 사이클을 위해 개발중인 애플리케이션의 상태를 저장해놓을 수도 있습니다. 하나의 상태 트리만을 가지고 있기 때문에 이전에는 굉장히 구현하기 어려웠던 기능인 실행취소/다시실행(undo/redo)을 손쉽게 구현할 수 있습니다.

2. State is read-only

상태를 변화시키는 유일한 방법은 무슨 일이 벌어지는 지를 묘사하는 액션 객체를 전달하는 방법 뿐이다.

이를 통해서 뷰나 네트워크 콜백에서 결코 상태를 직접 바꾸지 못 한다는 것을 보장할 수 있습니다. 모든 상태 변화는 중앙에서 관리되며 모든 액션은 엄격한 순서에 의해 하나하나 실행되기 때문에, 신경써서 관리해야할 미묘한 경쟁 상태는 없습니다. 액션은 그저 평범한 객체입니다. 따라서 기록을 남길 수 있고, 시리얼라이즈할 수 있으며, 저장할 수 있고, 이후에 테스트나 디버깅을 위해서 재현하는 것도 가능합니다.

3. Changes are made with pure functions

액션에 의해 상태 트리가 어떻게 변화하는 지를 지정하기 위해 프로그래머는 순수 리듀서를 작성해야합니다.

리듀서는 그저 이전 상태와 액션을 받아 다음 상태를 반환하는 순수 함수입니다. 이전 상태를 변경하는 대신 새로운 상태 객체를 생성해서 반환해야한다는 사실을 기억해야 합니다. 처음에는 하나의 리듀서만으로 충분하지만, 애플리케이션이 성장해나가면 상태 트리의 특정한 부분들을 조작하는 더 작은 리듀서들로 나누는 것도 가능합니다. 리듀서는 그저 함수이기 때문에 호출되는 순서를 정하거나 추가적인 데이터를 넘길 수도 있습니다. 심지어 페이지네이션과 같이 일반적인 재사용 가능한 리듀서를 작성하는 것도 가능합니다.

 

Redux flow

1. UI에서 컴포넌트 내에 존재하는 이벤트가 호출됩니다.

2. 이벤트와 연결된 Action Creator가 호출됩니다.

3. Action Creator에서 생성된 Action이 호출됩니다.

4. Action이 Reducer로 전달 됩니다. 이 과정을 Dispatch에서 담당합니다.

5. Reducer에서 Dispatch된 Action에 따라 상태 값을 변경합니다.

6. 변경사항이 렌더링되어 UI에 나타납니다.

 

 

반응형

'Study' 카테고리의 다른 글

Next.js 기초부터 알아보기  (0) 2023.01.10
스토리북으로 개발하기  (0) 2022.12.20
Jest로 테스트코드 작성하기  (0) 2022.12.12
Emotion의 배경지식 / 사용법 (CSS in JS)  (0) 2022.12.06
React Query  (0) 2022.11.28
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.