JS의 대표적인 중앙상태관리자인 리덕스에 대해 알아보도록 하겠습니다. 중앙상태관리자란, 상태 값들을 컴포넌트 단위로 저장하는 것이 아니라, 상태 값들을 따로 관리하여 참조하고, 변경할 수 있는 라이브러리입니다.
왜 중앙상태관리자가 필요할까요?? 아래 다이어그램으로 살펴보겠습니다.
몇 안되는 컴포넌트의 deps에서는 state Drilling을 통해 관리할 수 있겠지만, 만약 아래같은 상황이라면 어떨까요??
.
.
.
.
.
.
.
.
.
state Drilling이 도저히 감당할 수 없고, 거쳐가는 모든 컴포넌트들이 state를 들고 다녀야하는 말도안되는 상황이 생기게 됩니다.
그럼 저희가 오늘 알아볼 중앙상태 관리자가 도입된다면 어떻게 변화될까요?
상태관리를 담당해주는 중앙상태관리자로 인해 컴포넌트간 데이터 전송과 세팅이 굉장히 쉬워진 모습을 확인할 수 있습니다.
그럼 중앙상태관리자에 대해 알았으니 가장 많이 사용되고 있는 중앙상태관리자 "리덕스"에 대해 알아보도록 하겠습니다.
리덕스의 패턴 flux
리덕스는 flux패턴을 사용하여 데이터 흐름을 제어하고 있는데요. 여기서 Flux 패턴이 무엇인지 알아보도록 하겠습니다.
flux 패턴은 MVC패턴의 한계점을 극복하기 위해 등장한 데이터 흐름 패턴입니다.
MVC 패턴은 Model, View, Controller 의 구성으로 데이터를 관리합니다. Model에 데이터를 저장하고 View로 데이터를 보여주고, Controller로 데이터를 관리하는 형태입니다. 아래 그림은 MVC의 데이터 흐름을 한눈에 보기 좋게 정리한 그림입니다.
하지만 이러한 MVC 패턴은 양방향성 데이터 흐름이기에 어디서 어떻게 데이터가 변경되고 업데이트되는지 한눈에 확인하기 어렵고 선뜻 코드를 만지기 어렵다는 한계점이 존재했습니다. 아래 그림에서 보시는 것처럼 데이터 흐름에 의한 버그를 잡기위해 디버깅을 해야한다고 생각해보세요.. 모든 데이터 구조를 알아야 겨우 만져볼 수 있을 것 같습니다..
이러한 한계점을 극복하기위해 14년도에 Facebook에서 팔걷고 나섰습니다. 그리고 오늘 저희가 배울 리덕스의 근본이되는 Flux 패턴을 만들어냅니다.
Flux 패턴의 목적은 데이터의 흐름을 단방향으로 구성하서 애플리케이션의 구조를 보다 예측 가능하게 하기 위함이였습니다.
Flux 패턴은 보시는 것처럼
사용자 입력을 기반으로 Action을 만들고 해당 Action을 Dispatcher로 전달하여 Model(Store)의 데이터를 변경(저장)한 뒤, View에 반영하는 "단방향" 데이터흐름으로 진행되는 아키텍쳐입니다.
하나하나 뜯어보도록 하겠습니다.
Action
액션이란 데이터를 변경하는 행위로서 Dispatcher에게 전달되는 "객체"를 말합니다.
action에는 액션의 타입, 새로운 데이터를 묶어서 Dispatcher에게 전달하게 됩니다. 다시말해, 액션은 애플리케이션에서 발생하는 이벤트를 설명하는 객체입니다.
ex) 어명 (조선시대)
Dispatcher
디스패처는 모든 데이터의 흐름을 관리하는 중앙 허브입니다. 모든 액션을 dispatch를 통해 Model로 전송되고 관리됩니다.
ex) 조선시대 우체부
Model(Store)
스토어는 상태저장소입니다. 애프리케이션의 상태, 로직등을 보관합니다. 스토어는 디스패처로부터 액션을 받아 상태를 업데이트하고, 상태 변경을 구독하는 View에 이를 알립니다.
ex) 마을 정보게시판
View
뷰는 리액트의 컴포넌트라고 할 수 있습니다. 뷰는 스토어의 상태를 사용하여 사용자에게 정보를 표시하고 반대로 사용자의 상호작용을 액션으로 디스패처에 전달할 수 있습니다. 스토어의 상태가 변경되면 뷰는 이를 반영하여 업데이트를 진행합니다.
ex) 마을에 사는 사람들
예시를 통해 스토리를 설명해보겠습니다.
때는 조선시대, 어느 왕이 어명(액션)을 내립니다. "얼음 창고(state)의 갯수를 하나 늘리거라!" 조선시대 우체부(디스패처)는 어명을 들고 마을 게시판으로 뛰어갑니다. 그리고 마을 중앙의 정보게시판(Store)에 해당 어명(액션)을 반영시킵니다. 정보게시판이 내용이 변경되어 정보게시판에서 알림을 보냅니다. "위용위용! 얼음창고 건설에 관련된 사람들은 작업을 시작하시오!" 그럼 얼음창고에 관련(구독)된 사람들(View 컴포넌트)은 변경사항을 알고 할 일을 진행하고 얼음창고의 갯수가 수정되게 되는 것입니다.
억지로 끼워맞춰 설명드리려했더니 모호한 부분들이 좀 보입니다. '이러한 플로우로 진행되는구나' 라고만 생각해주시면 감사하겠습니다!
다시 본론으로 돌아와서 그럼 저희는 Flux패턴의 구성요소와 데이터흐름에 대해 알게되었습니다.
이전에 알아본 MVC 패턴보다 데이터 흐름을 예측하기쉽고 이에따라 확장성도 훨씬 개선된 패턴이라는 것이 느껴집니다.
그럼 이제 본격적으로 이 Flux패턴을 기반으로한 중앙상태관리자 "Redux"에 대해 알아보도록 하겠습니다.
리덕스
리덕스 공식문서에 따른 리덕스 소개는 다음과 같습니다.
"Redux는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너 입니다"
위에서 저희가 확인했듯 Flux패턴으로 인해 예측이 용이한 상태관리자라는 것을 어필하고 있습니다.
리덕스는 출범이후부터 많은 관심과 발전으로 인해 다른 상태관리 라이브러리에 비해 월등히 높은 사용량을 보여주고 있습니다.
리덕스의 기본 동작
// 생활코딩 Redux 참고 정리
// https://www.youtube.com/watch?v=N9PT9iNTZAE&list=PLuHgQVnccGMB-iGMgONoRPArZfjRuRNVc&index=2
리덕스의 관계 정리
위 그림은 생활코딩님이 정리하신 리덕스 동작의 지도입니다. 과정을 한번 살펴보겠습니다.
저희는 약속된 액션을 사용하여 그 값을 스토어의 디스패치에 전달합니다. 전달받은 액션은 리듀서에게 전달되고, 리듀서는 store에 해당 변경사항을 반영합니다. 그리고 값을 가지고 올 수 있는 getStore함수를 통해 다시 렌더링을하여 우리가 보고있는 웹브라우저에 반영됩니다. 추가로 구독(Subscribe)를 통해 액션이 디스패치를 통해 스토어에 상태변화를 전달할 때 이 "상태"를 구독(바라보고) 하고있는 모든 컴포넌트들을 재렌더링시켜 자동적으로 페이지에 변경사항을 반영할 수 있습니다.
실제 코드를 보며, 어떻게 작동되는지 확인해보겠습니다.
액션
상태 변화를 일으키기위한 객체입니다. 아래 코드에서는 INCREMENT, DECREMENT를 선언해보았습니다.
// 액션 타입 정의
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
// 액션 생성 함수
function increase() {
return { type: INCREMENT };
}
function decrease() {
return { type: DECREMENT };
}
리듀서 생성
상태 변화를 담당하는 함수입니다. 중요한 점은 "이전상태 (state) 와 새로운상태(Action)을 받아 새로운 상태를 반환한다" 는 것입니다.
초기 상태를 선언하고, 들어오는 액션에 따라 어떤 상태변화를 취할지 "약속"을 정해둘 수 있습니다.
// 초기 상태 정의
const initialState = {
count: 0
};
// 리듀서 함수
function counterReducer(state = initialState, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 };
case DECREMENT:
return { count: state.count - 1 };
default:
return state;
}
}
스토어 생성
모든 상태를 저장하고, 리듀서를 통해 값을 변경할 수 있습니다. createStore를 통해 생성할 수 있습니다.
import { createStore } from 'redux';
// 스토어 생성
const store = createStore(counterReducer);
디스패치
액션을 리듀서에게 가져다주는 역할을 합니다. store의 increase함수(약속, 예약어) 를 전달하여 상태변화를 요청합니다.
// 카운트 증가 액션 디스패치
store.dispatch(increase());
// 카운트 감소 액션 디스패치
store.dispatch(decrease());
값 가져오기 (상태확인)
getState를 통해 Store의 현재 상태를 확인할 수 있습니다.
console.log(store.getState()); // { count: 0 } 또는 액션 디스패치 후의 상태
긴 글 읽어주셔서 감사합니다!
'JavaScript' 카테고리의 다른 글
[JS] 실행 컨텍스트 뿌수기 #4 객체지향프로그래밍(OOP) (0) | 2024.03.04 |
---|---|
[JS] 실행 컨텍스트 뿌수기 #3 함수 (0) | 2024.02.29 |
[JS] 실행 컨텍스트 뿌수기 #2 렉시컬 환경 (0) | 2024.02.28 |
[JS] 실행 컨텍스트 뿌수기 #1 소스코드 (0) | 2024.02.28 |
[JS] Scope chaning (0) | 2024.02.20 |