참고자료 : 테코톡 Flux Architecture
리액트의 상태관리 라이브러리 중 하나인 redux에 대해 공부하던 중 Flux Arithitecture에 대한 내용이 나왔고 이에 대해 정리해보려한다.
Flux, 왜 필요한지?
Flux?
단방향 데이터 흐름을 통해 보다 예측 가능하게 상태를 관리할 수 있는 클라이언트 사이드 웹 애플리케이션 아키텍처
아래는 다익스트라께서 하신 말씀이다.
프로그래밍의 예술은 복잡성을 조직화하고, 다수를 제어하며, 혼돈을 가능한 효과적으로 피하는 것이다.
따라서 좋은 프로그래밍은 시스템의 복잡성을 낮추고 제어를 쉽게 만듦
MVC의 한계
이전의 웹 애플리케이션은 우리가 흔히 알고 있는 MVC 패턴을 사용했었다.
양방향 데이터 바인딩
위 그림에 의하면 Controller가 Model을 조작하고, Model이 View를 업데이트하며 View도 Model을 직접 업데이트할 수 있음을 알 수 있다.
Model과 View가 서로를 직접 업데이트하는 이 개념을 양방향 데이터바인딩이라한다.
위 그림 역시 MVC 패턴을 의미한다.
디자인 패턴은 특정 구현을 말하는 것이 아닌 추상적인 패턴을 의미하므로 위의 그림처럼 구현 방식이 달라질 수 있다.
MVC는 확장 가능하지 않다?
- React를 만든 페이스북은 MVC의 양방향 데이터바인딩이 애플리케이션의 복잡도를 높이고 확장을 어렵게 만든다고 판단하였다.
서로가 서로를 수정 할 수 있기에 애플리케이션의 복잡도가 높아질 수록 데이터 흐름을 파악하기 어렵다.
MVC에서 FLUX로
이러한 불편함을 느낀 페이스북은 어떻게 FLUX라는 아키텍처를 제안했을까?
- 데이터의 흐름을 단방향으로 고정한다.
사진을 보면 화살표가 Dispatcher를 거쳐 사이클을 이루는 것을 볼 수 있다.
FLUX 패턴의 예제
만약 메시지 시스템을 개발한다고 가정해보자
위의 그림에서 새로운 메시지 핸들러는 새로운 기능이 추가될 때마다 점점 복잡해지고 있다.
따라서 새로운 메시지 핸들러를 삭제하고 각 View가 자신의 상태를 직접 변경하도록 수정해봤다.
하지만 아래의 읽지 않음 카운터는 다른 View의 상태를 의존하기 때문에 새로운 메시지 도작이라는 상태만으로는 자신의 상태를 변경할 수 없다.
따라서 새로운 메시지 도착보단 좀 더 독립적인 상태 저장방식이 필요하다.
따라서 아래 그림처럼 전역 애플리케이션 상태 저장소를 사용하겠다.
이제 새로운 메시지가 도착하면 각 저장소가 새로운 메시지를 받아 자신의 상태를 변경하는 로직을 가짐
이제 읽지 않음 카운터라는 뷰는 읽지 않은 스레드들의 개수를 보여주기만 하면 됨
이제 핸들러가 챗 탭이 열렸는지 메인 메시지 뷰가 열렸는지 확인하지 않고 View에서 직접 스레드들을 읽었다고 판단하여 저장소에게 읽음으로 표시 알림을 알릴 수 있게 됨
View에서 발생한 읽음으로 표시는 읽지 않은 스레드들 저장소로 전달되어 해당 스레드를 읽음으로 표시하고 저장소가 직접 읽은 스레드를 제거할 수 있음
이제 각 요소들을 더 추상화해서 개념을 알아보자
액션은 전역 애플리케이션 상태 저장소들에게 전달되고 View는 자신이 관심있어하는 상태를 가져와 화면에 그려준다.
View에서 UI Interaction(버튼과 같은 상호작용)과 같은 액션이 발생하면 이 액션은 다시 상태 저장소들에게 전달된다.
하지만 여기서 문제가 있다
새로운 메시지 도착 액션은 액션이름과 메시지 내용을 담고 있는 단순한 자바스크립트 객체이다.
따라서 상태 저장소에 액션이 직접 전달할 수 없다.
따라서 액션허브를 만들어서 상태 저장소에 액션을 전달한다.
액션을 어떤 저장소에 저장할지 일종의 교통을 정리해주는 역할이라고 보면된다.
그림을 단순화 해보자.
단순화 해보면 아까전의 단방향 데이터바인딩과 유사한 형태임을 알 수 있다.
각 개념들 구체화
Action
상태 변경 요청을 담은 자바스크립트 객체
저장된 내용
- 액션 이름(type)
- 데이터(payload)
- Action 생성자
Action을 쉽게 만들어주는 도우미
Flux에서 애플리케이션은 이러한 액션을 통해서만 상태 변경을 요청할 수 있다.
그리고 액션 생성자라는 것을 사용할 수 있는데, 액션을 쉽게 만들어주는 도우미 함수라고 보면 된다.
Dispatcher
모든 데이터 변경 요청이 경유하는 중앙 허브
- View로부터 Action을 받아 모든 Store들에게 전송
- 내부에 상태 변경 로직이 존재하지 않음
- Store간 의존성 관리
Store A의 상태 변경 순서를 Store B 다음으로 미룰 수 있음
Store
애플리케이션 상태 및 로직 컨테이너
- Dispatcher에서 전달된 Action을 통해서만 상태 변경
- 상태가 변경되면 View에게 통지
View
상태에 따라 화면을 출력
- Controller-View(React)
Store가 통지하는 상태 변경을 수신, 받은 상태에 따라 View를 새로 렌더링 - Dispatcher에게 Action을 전달
정리
View에서 Action이 발생하면 Dispatcher가 이를 수신해 각 Store들에게 순서대로 전달함
액션을 전달 받은 Store는 관심있는 Action에 대해서 상태를 변경하고 변경된 상태를 View에게 알려줌 View는 변경된 상태에 따라 화면을 새로 그림
만약 View에서 다른 Action이 발생한다면 해당 사이클이 반복
이러한 엄격한 단방향 데이터 흐름을 통해 Flux는 애플리케이션을 단순하게 유지하고 항상 최신 버전의 상태를 View를 통해 보여줄 수 있음
장점과 한계점
장점
- 데이터 흐름의 구조화
유지보수에 용이하고 새로운 기능에 열려있음 - 쉬운 유닛 테스트
Dispatcher는 Action을 받아 상태를 변경하는 순수 함수임
외부의 상태에 영향을 받지 않아 격리된 환경에서 쉽게 테스트할 수 있음
이와 같은 장점으로 Flux 패턴을 사용하면 대규모 애플리케이션에서도 상태관리를 쉽게할 수 있음
단점
- 초기의 작은 기능을 정리하기 위해 상대적으로 많은 코드가 필요
이는 높은 학습 곡선과 장황한 문법이 필요
이를 해결하기 위해 redux와 같이 Flux를 발전시킨 다양한 라이브러리들이 등장했음
'CS > 테코톡' 카테고리의 다른 글
프론트엔드 성능 측정 (2) | 2024.12.06 |
---|---|
리액트 렌더링 최적화 (1) | 2024.12.06 |
CSS 프레임워크(Tailwind) (1) | 2024.12.06 |
쿠키와 웹 스토리지 (0) | 2024.12.06 |
React-Query에 대해 알아보자 (0) | 2024.12.06 |