개발/프론트엔드

Flux 패턴

paice 2024. 9. 17. 22:55

전역 상태 관리 흐름 이해하기

React에서 PropsState는 부모 컴포넌트와 자식 컴포넌트 또는 한 컴포넌트 안에서 데이터를 다루기 위해 사용됩니다. 이 Props와 State를 사용하게 되면 부모 컴포넌트에서 자식 컴포넌트, 즉, 위에서 아래, 한쪽으로 데이터가 흐르게 됩니다.

 

만약 다른 컴포넌트에서 한쪽으로 흐르고 있는 데이터를 사용하고 싶은 경우, 또는 다른 컴포넌트에서 사용하고 있는 데이터를 현재의 데이터 흐름에 넣고 싶은 경우가 발생한다면 어떻게 해야할까요?

 

사용하고 싶은 데이터와 이 데이터를 사용할 컴포넌트의 공통 부모 컴포넌트에 State를 만들고, 사용하고자 하는 데이터를 Props로 전달하면 이 문제를 해결할 수 있습니다.

 

하지만 이처럼 컴포넌트 사이에 공유되는 데이터를 위해 매번 공통 부모 컴포넌트를 수정하고 하위 모든 컴포넌트에 데이터를 Props로 전달하는 것은 매우 비효율적입니다. 이와 같은 문제를 해결하기 위해 React에서는 Flux라는 개념을 도입하였고 그에 걸맞은 Context API를 제공하기 시작했습니다.

 

여기서 Flux라는 개념이 나오는데, 이를 자세히 알아봅시다!


리액트를 개발한 페이스북은 왜 Flux 패턴이 필요했던 걸까요?

 

그 답은 대규모 애플리케이션에서 데이터 흐름을 일관성 있게 관리함으로써

프로그램의 예측가능성(Predictability)을 높이기 위함이었습니다.

먼저 기존 애플리케이션들이 보편적으로 사용하던 MVC 패턴에 대해 알아봅시다.

mvc 패턴

MVC는 Model, View, Controller의 약자입니다.

Model에 데이터를 저장하고, Controller를 이용하여 Model의 데이터를 관리(CRUD)합니다.

(Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말)

 

Model의 데이터가 변경되면 View로 전달되어 사용자에게 보여집니다. 또한 중요한 점은 사용자가 View를 통해 데이터를 입력하면 View 역시 Model을 업데이트할 수 있다는 점입니다.

데이터가 양방향으로 흐를 수 있다는 것입니다.

문제는 바로 여기서 시작됩니다. 애플리케이션의 규모가 커지고 커져서 다음과 같은 구조가 나타나게 되는데요,

View가 다양한 상호작용을 위해 여러 개의 Model을 동시에 업데이트하고, Model 역시 여러 개의 View에 데이터를 전달하는 상황이 발생하면 이러한 복잡한 데이터 흐름을 가지게 됩니다. 이렇게 많은 의존성을 가지면 Model의 개수가 많아질수록 각 Model에서 발생한 이벤트가 애플리케이션 전체로 퍼져나갈 때 이를 예측하기 힘들어 집니다.

페이스북은 “MVC는 정말 눈 깜짝할 사이에 복잡해진다”고 말하며 이 문제의 해결 방안으로 단방향 데이터 흐름을 가지는 Flux 패턴을 고안해냈습니다.

 

Flux는 사용자 입력을 기반으로 Action을 만들고 Action을 Dispatcher에 전달하여 Store(Model)의 데이터를 변경한 뒤 View에 반영하는 단방향의 흐름으로 애플리케이션을 만드는 패턴입니다.

기본적인 Flux의 형태
view는 사용자의 상호작용에 응답하기 위해 새로운 action을 만들어 시스템에 전파

  • Action
    • Action 정보를 담고 있는 객체를 만들어내 Dispatcher에 전달하는 역할
  • Dispatcher
    • Flux의 모든 데이터 흐름을 관리하는 중앙허브
    • 들어오는 Action 객체 정보를 받아 실제로 어떤 행동을 할지 결정하는 곳
  • Store
    • 데이터와 데이터를 가공하는 로직을 가지고 있음
    • Dispatcher에 자신을 등록하고 Callback을 제공
    • Action이 넘어오면 등록된 Callback을 활용해 타입에 맞는 로직을 실행하고 데이터를 업데이트
    • 변경된 데이터를 View에게 알림
  • View
    • 리액트 컴포넌트로 생각하면 됨
    • store에서 어떤 이벤트가 발생하거나 변경되면 View는 변경된 점을 가져오고, 이를 바탕으로 화면을 다시 렌더링