평소에는 상태관리를 할 때 깊게 들어갈 생각보다는 그냥 이용만 했던 것 같다. Redux나 Recoil, Zustand 같은 상태 관리 라이브러리는 많지만, 단순히 라이브러리를 이용만 하는 것보다는 패턴에 대해서 이해하고 활용하는 것은 큰 차이가 있을 것 같다고 생각해서 이번 글을 작성해보려고 한다.
Flux 패턴에 대해서 📚
Flux 패턴은 어떻게 등장했나?
Flux 패턴은 지금은 Meta로 사명을 바꾼 페이스북에서 싱글 페이지 웹 애플리케이션을 구축할 때 사용하기 위해서 만들었다. 이 패턴을 이해하기 위해서 먼저 양방향 데이터 흐름과 단방향 데이터 흐름에 대해서 알고 가야한다.
양방향 데이터 흐름 🔄
일반적으로 MVC(Model-View-Controller) 구조가 양방향 데이터 흐름을 가진다. MVC는 모델이 업데이트되면 뷰를 업데이트하고, 해당 뷰는 또 다른 모델을 업데이트할 수 있다. 이런 식으로 각 계층이 너무 많은 상호작용을 하기 때문에 예측하기 힘들고, 로직이 복잡해질 수 있다.
단방향 데이터 흐름 ➡️
그렇다면 단방향 데이터흐름은 무엇일까? 말그대로 한 쪽 방향으로만 데이터가 흐른다는 것인데, 이렇게 되면 데이터가 일관적으로 흐르기 때문에 상태 변화를 쉽게 추적할 수 있다.
Flux의 동작 과정 🧩
플럭스 패턴의 구성요소에는 Action, Dispatcher, Store, View가 있다.
| Action
액션은 애플리케이션에서 일어나는 이벤트를 나타낸다.
사용자의 상호작용이나 서버의 응답 같은 애플리케이션의 상태 변화를 일으키는 모든 사건들을 의미한다.
액션의 형태는 일반적으로 액션의 종류를 구분하는 type과 데이터를 포함하는 payload로 구성된다.
const action = {
type = "INCREMENT"
payload = 5
}
| Dispatcher
디스패처는 액션을 받아서 처리하는 주체이다. 모든 데이터의 흐름을 관리하는 중앙 허브로 사용된다.
| Store
스토어는 애플리케이션의 상태와 로직을 포함하는 저장소이다. 디스패처에 등록되어 액션에 따라 상태를 변경하는 로직을 포함한다.
| View
사용자 인터페이스를 의미한다. (UI)
스토어에서 상태를 받아서 화면을 그리거나, 사용자의 입력을 기반으로 액션을 생성한다.
View에서 사용자가 어떤 Action을 하면 해당 Action은 Dispatcher로 이동해서 어떤 액션인지에 따라 Store에 값을 반영한다. Store에 값이 변경되면 해당 Store를 사용하는 View를 리렌더링한다.
Flux의 장점 👍
플럭스의 강점은 예측 가능성을 높이고 디버깅 용이성을 높이는 것이다.
어떤 액션에 대해서 디스패쳐에서만 판단하고 스토어에 값을 반영하기 때문에 디스패처와 스토어만 봐도 되기 때문에 편리하다고 생각한다. 기존에는 모델을 업데이트하는 뷰를 찾고, 또 뷰가 업데이트하는 모델을 찾아야하기 때문에, 코드베이스가 점차 커질 수록 특정 문제가 발생했을 때 발생한 위치를 찾기 힘들어진다.
플럭스 패턴을 적용한다면 뷰에서 어떤 액션을 생성하는지를 관리하고, 디스패쳐에서 어떻게 스토어에 값을 반영할지를 고민하면 되기 때문에 좀 더 일관적이 예측이 쉬워지고 그로인해 문제가 생긴 곳을 빠르게 찾아낼 수 있기 때문에 디버깅까지 용이해지는 효과를 가져온다.
Flux의 단점 🤯
복잡한 개념, Action, Dispatcher, Store, View 구조에 대해 이해를 하고 사용해야 하기 때문에 처음에 작성하려고하면 어려움을 겪을 수 있다. 나도 처음에 Redux 강의를 들었을 때 Flux 패턴에 대해서 들었지만, 솔직히 완벽하게 이해하지 않고 넘어갔던 것 같다. 어느정도 프로젝트 경험이 쌓이고 나서 다시 Flux 패턴을 보니 이해가 잘되는 것 같다.
많은 코드 작성, 이 부분도 좀 공감이 간다. 뷰-스토어 구조를 구현하려면 처음에는 직관적이지 않은 코드(당장 뷰를 업데이트하는 코드가 아니라 상태가 변경되었을 때 리렌더링을 촉발하는 코드)를 많이 작성해야한다.
MVC 구조 같은 경우에는 필요에 따라 코드를 작성하면 돼서 바로바로 이해가 되는 코드를 작성 가능한데, 뷰-스토어 구조는 초기에 패턴 구조를 구현하기 위해 작성해야하는 코드의 양이 많아서 어렵다고 생각한다. 하지만 처음 만들때가 제일 복잡하고 후에는 간단한게 관리가 가능했던 경험이 있다.
간단한 예제
간단한 예시로, 화면(view)에 있는 카운터 버튼을 누르면 액션 생성자(action creater)에 의해서 action이 생성된다. 해당 액션은 dispatcher로 전달되어 등록된 모든 스토어에게 액션을 보낸다.
이 예제에서는 INCREMENT 액션과 DECREMENT 액션이 존재하고 디스패처에서는 들어온 액션을 순차적으로 등록된 스토어들에게 전달한다.
스토어(store)에서는 액션의 type이 INCREMENT이면 값을 더하고, DECREMENT이면 빼서 스토어에 값을 업데이트한다. 스토어는 갖고 있는 상태가 변경되면 해당 스토어를 구독하고 있는 화면을 다시 그린다. (Re-rendering)
See the Pen Untitled by JeongwooSeo (@ShipFriend0516) on CodePen.
내 생각 💭
개발을 처음 시작할 때는 이런 디자인 패턴에 대해서 중요하게 생각하지 않았다. "뭐 이런 것까지 알아야해~" 이런 느낌으로 훑고 넘어가는 느낌으로만 공부했었는데, 최근에 직접 구현해보고 나니 왜 이런 패턴들이 등장했는지를 직접 느낄 수 있었다.
과거의 전통적인 웹페이지에서는 복잡한 데이터 교환이 이루어지지 않기 때문에 이런 데이터 흐름을 정의할 필요가 없었다고 생각한다. 하지만 최근 들어서 복잡해지고 있는 웹 앱에서는 너무나 많은 상태와 로직을 클라이언트측에서 관리해야한다.
이런 상황에서 양방향으로 데이터를 조작하게 된다면, 개발자가 애플리케이션의 흐름을 예측하기 힘들어지는 상황이 만들어진다. 그러니까 양쪽 방향으로 흐르던 데이터를 한 쪽 방향으로 고정시켜서 전체적인 흐름의 예측 가능성을 높이려고 Flux 패턴이 만들어진 것 같다고 생각한다.
'Web > Frontend' 카테고리의 다른 글
react-icons 라이브러리로 알아보는 트리 쉐이킹 (0) | 2024.11.03 |
---|---|
React에서 이벤트를 처리하는 방법 with 이벤트 위임과 합성 (6) | 2024.10.06 |
[React] useEffect 역할과 사용 방법 (1) | 2024.09.29 |
드래그 앤 드롭 기능 구현과 dragover 성능 최적화까지 (0) | 2024.09.08 |
oraciondev 님의 블로그 입니다.
안녕하세요