개발/Front-end

Flux 패턴

devriver 2021. 8. 2. 23:42

페이스북은 Flux 패턴을 왜 만들었을까?

페이스북은 기존의 MVC 패턴이 프로젝트 규모가 커질수록 빠른 속도로 복잡해진다고 결론 내렸다. 프로젝트의 구조가 복잡하면 코드 예측이 어려워지고, 새로운 개발자가 적응하는 데 많은 시간이 필요해지고, 테스트가 어려워진다. MVC 패턴은 아래 그림처럼 모델-뷰가 양방향 통신이 가능하다. 이는 두 개 이상의 모델을 순차적으로 업데이트 하는 기능을 구현할 때 모델 간의 의존성을 높이는 문제를 만들고 종종 데이터 흐름을 꼬이게 한다.

예시) 유저가 뷰에서 액션(키보드, 마우스 등)을 하여 컨트롤러에게 명령이 전달되면 컨트롤러는 A모델을 업데이트 하고 B모델도 업데이트 한다. B 모델의 업데이트가 또 다른 C뷰에 영향을 끼치고 C뷰는 컨트롤러를 거쳐 D모델의 상태를 변경시킬 수 있다. 양방향 통신은 이러한 연쇄적인 트리거를 만들어 낼 수 있다.

Flux%20%E1%84%91%E1%85%A2%E1%84%90%E1%85%A5%E1%86%AB%20aad6e4d02e6a4aa8a650a32ae0d2c9d1/Untitled.png

Flux 패턴이란?

Flux에서는 항상 데이터가 단방향으로 흐른다. 언제나 디스패쳐 → 스토어 → 뷰 → 액션 → 디스패쳐 .. 로 흐른다.
데이터를 뷰에서 직접 수정할 수 없고 반드시 액션을 통해서만 수정이 일어나기 때문에 양방향보다 데이터의 흐름을 예측하기 쉬워진다.

Flux%20%E1%84%91%E1%85%A2%E1%84%90%E1%85%A5%E1%86%AB%20aad6e4d02e6a4aa8a650a32ae0d2c9d1/Untitled%201.png

Flux%20%E1%84%91%E1%85%A2%E1%84%90%E1%85%A5%E1%86%AB%20aad6e4d02e6a4aa8a650a32ae0d2c9d1/Untitled%202.png

Flux 패턴의 구성요소

단일 Dispatcher

모든 데이터 흐름을 관리하는 허브(교통정리) 역할을 한다. 액션 생성자가 새로운 액션을 디스패처에게 알려주면 디스패처는 스토어에게 제공받은 콜백 함수를 실행하여 액션을 스토어에게 전달한다. 애플리케이션 규모가 커지게 되면 디스패처의 역할이 더욱 중요해진다. 바로 스토어 간의 의존성을 특정적인 순서로 콜백을 실행하는 것으로 관리하기 때문이다. 스토어는 다른 스토어의 업데이트가 끝날 때까지 기다릴 수 있고 끝나는 순서에 따라 스스로 갱신된다.

Stores

스토어는 애플리케이션의 상태와 로직을 가지고 있다. 스토어는 단순히 ORM 스타일의 객체 컬렉션(DB 레코드)을 관리하는 것을 넘어 개별적인 도메인에서 상태를 관리한다. 스토어는 자신을 디스패처에 등록하고 콜백을 제공한다. 콜백은 액션 타입을 파라미터로 받고 switch문을 사용하여 액션 타입에 따라 스토어 내부 메소드에 연결될 수 있는 적절한 훅을 제공한다.

Views와 Controller-Views

컨트롤러-뷰란?

뷰들의 최상위 레이어로 스토어의 데이터를 자식 뷰에게 전달하는 역할을 한다.

  1. 스토어가 상태가 변경되었다고 이벤트를 보내면 컨트롤러-뷰는 스토어의 public getter 메소드를 통해 필요한 데이터를 요청한다.
  2. setState() 또는 forceUpdate()를 호출한다.
  3. 2번 호출은 자동으로 render() 와 하위 모든 자식 뷰의 render() 메소드를 실행시킨다.

컨트롤러-뷰가 전체 스토어 상태를 단일 객체로 만들어 하위 뷰들에 전달하는 덕분에 자식 뷰들은 데이터에 따라 UI를 렌더링하는 순수 함수로 유지될 수 있다.

레이어 중간에 컨트롤러-뷰를 추가할 때 고려해야할 점

때로는 레이어 중간에 컨트롤러-뷰를 넣어 특정 도메인과 관계된 뷰들을 감싸서 독립적으로 만들 수 있다.(일종의 캡슐화) 이 때 데이터의 흐름의 단순함을 유지해야 한다. 캡슐화 된 단순한 컴포넌트와 여러 방향으로 흐르는 데이터의 복잡도의 균형을 잘 판단해서 컨트롤러-뷰를 만들어야 한다. 자칫하면 다른 컨트롤러-뷰에 의해 리액트render() 메소드가 반복적으로 실행되어 디버깅을 어렵게 할 수 있다.

참고

https://taegon.kim/archives/5288

https://haruair.github.io/flux/docs/overview.html#content