728x90
Redux, Zustand 같은 전역 상태관리 라이브러리는 Flux 패턴을 기반으로 만들어졌다.
나는 이미 Redux를 사용해봤기 때문에 Flux 패턴에 대해서도 특징과 장단점을 알고 있지만, 텍스트로 정리해두면 좋을 것 같아서 기본적인 개념부터 이와 반대되는 패턴들까지 정리해본다.✍

Flux 패턴
웹 애플리케이션의 전역 상태 관리를 더욱 효율적이고 일관되게 할 수 있도록 설계된 아키텍처 패턴.
2014년에 Facebook에 의해 개발되었으며, 다양한 JS 라이브러리나 프레임워크에서 사용되지만 특히 React에서 주로 사용되고 있다. 단방향 데이터 흐름을 통해 상태 변경을 명확하게 추적하고 관리할 수 있다는 장점이 있다.
Flux 패턴의 특징
- 단방향 데이터 흐름 (Unidirectional Data Flow): 데이터가 한 방향으로만 흐르도록 설계되어 있어서, 상태 변화가 예측 가능하고 디버깅이 용이하다.
- 명확한 상태 관리: 상태 변화의 흐름이 잘 정의되어 있어, 각 Action이 상태에 미치는 영향을 쉽게 이해할 수 있다. 이는 대규모 애플리케이션에서 유지보수성과 팀 내 협업을 원활하게 한다.
- 비동기 작업 처리: 비동기 작업을 효율적으로 처리하기 위해 미들웨어를 도입할 수 있다. 이를 통해 API 호출 등과 같은 비동기 작업을 잘 관리할 수 있다.
Flux 패턴의 구성요소와 작동원리
사실 Redux를 처음 배울 때, 가장 어렵게 느껴졌던 부분이 여기였다.
구성요소가 많은데, 각자 역할이 있고 이동되는 방향도 정해져있다. 학습 진입장벽이 높은 편이라는 것이 추후 설명할 Flux 패턴의 단점 중 하나이기도 하다. 일단 구성요소와 작동원리부터 설명해보자면,
Flux 패턴의 구성요소:
- Action: 애플리케이션에서 발생하는 이벤트, 컴포넌트에서 스토어에 보낼 객체 형태의 데이터.
사용자가 버튼을 클릭하거나 서버로부터 데이터를 받아올 때 Action이 생성된다.
Redux에서는 Reducer 함수가 수행할 작업이다. Reducer는 Action을 보고 어떤 상태로 변경할지 결정한다. - Dispatch: 모든 Action을 받아서 이를 처리할 Store로 전달하는 중앙 허브.
쉽게 말해, 실제로 Action을 실행하는 공간이다. Dispatch는 Action의 흐름을 관리한다. - Store: 애플리케이션의 상태를 저장하고 관리하는 공간.
Store는 Action을 받아서 상태를 업데이트하고, 상태 변경을 구독하는 View에게 알린다.
Store에 있는 상태는 직접 수정할 수 없고 Action을 통해서만 변경된다.
Redux에서는 여기에 현재 애플리케이션 상태와 Reducer 함수가 들어있다. - View: 사용자에게 보여지는 UI 구성 요소. Store의 상태를 구독하고, 상태가 변경될 때마다 다시 렌더링한다.
Flux 패턴의 작동 원리:
- Action 생성: 버튼 클릭 등의 이벤트가 발생하면 Action이 생성된다. 예를 들어, ADD_TODO라는 Action이 있을 수 있다.
- Dispatch로 Action 전달: 생성된 Action은 Dispatch에 전달되고, Dispatch는 이를 받아서 적절한 Store에 전달한다.
- Store 상태 업데이트: Store는 Dispatch한테서 Action을 받고, 그에 맞는 로직에 따라 자신의 상태를 업데이트한다. 예를 들어, 새로운 Todo 항목을 추가하거나 삭제하는 등의 작업이 수행된다.
Redux의 경우, 여기에서 Reducer가 Store한테 상태와 액션을 전달받고, 액션에 따라 새로운 상태를 반환한다. - View 업데이트: 상태가 업데이트되면 Store는 자신의 상태를 구독하고 있는 View에게 알린다. View는 상태를 기반으로 다시 렌더링되어 사용자에게 새로운 UI를 보여준다.
Flux 패턴의 장단점
장점 | - 예측 가능성: 데이터 흐름이 단방향으로 정의되어 있어, 상태의 변화를 쉽게 추적할 수 있다. - 디버깅 용이성: 상태 변경의 흐름이 명확하여, 문제를 찾고 수정하기 쉽다. - 유지보수성: 각 구성 요소가 명확하게 분리되어 있어 코드의 가독성이 높아진다. |
단점 | - 복잡성: 어쩌면 가장 큰 단점일지도 모르겠다. Flux 패턴의 단방향 데이터 흐름은 프로젝트가 커질수록 코드의 복잡성을 증가시킬 수 있다. 모든 상태를 스토어에서 관리하기 때문에, 스토어나 액션이 많아진다면 스토어의 관리가 어려워진다. 또한 비동기 작업(예: API 호출)을 처리할 때, 미들웨어를 사용해야 하는 경우가 많아져 추가적인 복잡성이 발생한다. 이를 처리하려고 Redux Thunk, Redux Saga와 같은 라이브러리를 사용하는 것이 일반적이다. - 상태 관리의 수동성: Flux 패턴은 액션이 발생할 때마다 스토어를 업데이트해야 한다. 상태 변경이 자동으로 이루어지지 않기 때문에, 개발자가 수동으로 상태를 관리해야 하는 부담이 있다. - 보일러플레이트 코드: Flux 패턴을 사용할 때는 액션, 디스패치, 스토어 등의 구조를 설정하기 위한 보일러플레이트 코드가 많아지기 쉽다. 특히 작은 프로젝트에서는 프로젝트의 크기에 비해 보일러플레이트 코드가 많아서 유지보수가 어려울 수 있다. - 배우기 어려움: 개발자가 Flux 패턴을 처음 접할 때 이해하기 어려울 수 있다. Action, Dispatcher, Store 간의 상호작용을 명확히 이해해야 하므로, 학습 진입장벽이 존재한다. - 성능 문제: 모든 상태 변화가 View에 알림을 보내야 하므로, 상태가 자주 변하는 경우 불필요한 렌더링이 발생할 수 있다. 이는 성능에 악영향을 미칠 수 있다. |
Flux 패턴을 사용하는 기술
Redux | Flux 아키텍처의 원칙을 바탕으로 만들어진 라이브러리. 단일 스토어를 사용하여 애플리케이션의 모든 상태를 전역적으로 관리할 수 있고, redux-thunk나 redux-saga와 같은 미들웨어를 사용하면 API 호출과 같은 비동기 요청을 효율적으로 처리할 수 있다. 또한 크롬 브라우저의 Redux DevTools를 통해 상태의 변화를 시각적으로 추적할 수 있는 장점이 있다. ※ Redux 기본 개념 정리 - https://hjinn0813.tistory.com/48 ※ Redux-Thunk, Redux-Saga 개념 정리 - https://hjinn0813.tistory.com/104 |
Zustand | Flux 패턴의 기본 아이디어를 바탕으로 한 경량의 상태 관리 라이브러리. React의 Context API를 사용하여 전역 상태를 더욱 쉽게 관리할 수 있다. 상태 변경 시 구독된 컴포넌트만 리렌더링되도록 최적화되어 있어, 성능이 뛰어나다. 주로 작은 프로젝트나 간단한 상태 관리가 필요한 경우에 유용하다. ※ Zustand 기본 개념 정리 - https://hjinn0813.tistory.com/132 |
Recoil | Flux 패턴의 영향을 받으면서도 더 유연하고 직관적인 상태 관리를 제공한다. Facebook에서 2020년에 개발한 상태 관리 라이브러리로, React에 최적화되어 있다. 상태를 정의하는 기본 단위인 Atom과 파생 상태를 계산하는 Selector를 사용하여 컴포넌트 간의 상태 공유를 쉽게 관리한다. Atom은 여러 컴포넌트에서 공유할 수 있으며, Atom의 값이 변경되면 이를 구독하고 있는 컴포넌트가 자동으로 리렌더링된다. Selector는 다른 Atom이나 Selector의 값을 기반으로 새로운 값을 생성하여, 복잡한 상태 관리를 간편하게 만들어준다. 또한 비동기 작업을 위한 Selector도 쉽게 만들 수 있어 API 호출을 간단하게 처리할 수 있는 기능을 제공한다. |
MobX | 반응형 프로그래밍(reactive programming) 원칙을 기반으로 한 경량의 상태 관리 라이브러리. 상태 변화가 자동으로 UI에 반영되는 기본 구조는 Flux 패턴의 영향을 받아 설계되었다. 상태는 관찰 가능하게 만들어지며, 어떤 부분에서 상태가 변경되었는지를 쉽게 추적할 수 있어서 개발자가 명시적으로 상태 변화를 처리할 필요가 없다. 또한 상태를 객체로 표현하고, 비즈니스 로직을 해당 객체와 함께 관리함으로써 코드의 구조를 명확히 하고 유지보수를 용이하게 만든다. 작은 프로젝트에서도 쉽게 사용할 수 있으며, 상태 변경이 자동으로 UI에 반영되는 방식으로 동작한다. |
Flux 패턴과 반대되는 개념들
- 양방향 데이터 흐름 (Bidirectional Data Flow):
Flux 패턴은 단방향 데이터 흐름 기반이지만, 양방향 데이터 흐름은 데이터가 양방향으로 흐를 수 있는 구조이다. 예를 들어, AngularJS와 같은 프레임워크는 양방향 데이터 바인딩을 사용하여 모델과 뷰가 서로 직접적으로 연결되어 있다. 이렇게 되면 UI의 변화가 모델에 즉시 반영되고 모델의 변화도 UI에 즉시 반영된다. 이런 구조를 사용하는 아키텍처 패턴은 MVC, MVVM 등이 있다.- MVC(Model-View-Controller): Model(데이터), View(사용자 인터페이스), Controller(비즈니스 로직)로 구성되어 View가 Model에 직접 접근하고 변경할 수 있다.
- MVVM(Model-View-ViewModel): ViewModel을 통해 View와 Model 간의 상호작용을 관리한다. View는 ViewModel에 바인딩되어 있어, 데이터가 변경될 때 ViewModel이 이를 반영한다. 이 방식은 데이터 바인딩을 통해 양방향 흐름을 허용한다.
- 이벤트 중심 아키텍처(Event-Driven Architecture):
시스템의 구성 요소가 이벤트를 기반으로 상호작용하는 방식.
이벤트가 발생하면 이를 처리하기 위한 여러 리스너나 핸들러가 존재하며, 이벤트는 시스템의 다른 부분에 알림을 주는 역할을 한다. 이벤트 생산자와 소비자가 서로 직접 연결되지 않기 때문에 시스템의 유연성과 확장성이 높아진다. 여기서 이벤트 생산자는 '이벤트를 발생시키는' 주체, 소비자는 '이벤트를 처리하는' 주체를 말한다. 버튼 클릭 이벤트를 예로 들자면, 생산자는 버튼이고 소비자는 클릭 이벤트를 처리하는 핸들러 함수가 된다.
또한 비동기 처리에 유리하여, 이벤트 발생 시 즉시 반응하지 않고 필요할 때 소비할 수 있다.
예를 들어, 사용자 클릭이나 외부 API 호출 등의 이벤트가 발생했을 경우에 해당 이벤트를 수신하여 처리하는 방식이 있다. - 이벤트 소싱 패턴(Event Sourcing):
애플리케이션의 상태를 이벤트로 기록하고, 이를 기반으로 현재 상태를 복원하는 방식.
이벤트는 변경되지 않으며, 모든 상태 변화는 새로운 이벤트로 기록되기 때문에 상태의 불변성을 강조한다. 이벤트 저장소를 통해 애플리케이션의 상태를 복원할 수 있어서 상태 이력 추적 및 재현이 가능하다.
예를 들어, 금융 거래 애플리케이션에서 각 거래를 이벤트로 기록하고, 이러한 이벤트를 통해 사용자의 잔액이나 거래 내역을 재구성하는 경우가 있다.
이렇게 Flux 패턴에 대해서 정리하니까 전보다 Redux와 친숙해진 느낌이 든다.😆
며칠 전에 본 유튜브 영상에서 나온 말이지만, 프론트엔드 개발자에게 "어떻게 하면 더욱 효율적이고 편리하게 상태 관리를 할 수 있는가"는 정말 끊임없이 연구해야하는 과제인 것 같다. 일단 나는 Redux는 복잡하니까 Zustand를 조금 더 공부해봐야지..

728x90
'💻 Frontend > Redux, Zustand' 카테고리의 다른 글
Zustand 실습 (코드 리팩토링) (0) | 2024.10.21 |
---|---|
Zustand 기본 개념 정리 (2) | 2024.10.14 |
Redux-thunk, Redux-saga 개념 정리 (0) | 2024.08.16 |
[코딩온] 프론트엔드 입문 Day 46 (React Redux) (0) | 2024.04.23 |