지금은 react에서 데이터 관리를 할 때 redux를 쓰는 게 당연시되고 있다.

그럼 리액트는 왜 줄곧 MVC패턴을 사용하다가 flux패턴을 사용하게 되었는지 알아보자.

 

Flux 출현 배경: 기존 MVC 모델의 한계

 

기존의 어플리케이션 환경에서 보편적으로 사용되는 패턴은 MVC였다.

Model에 데이터를 정의해 두고, Controller를 이용해 Model 데이터를 생성 / 조회 / 수정 / 삭제(CRUD)하고,

변경된 데이터는 View에 출력되면서 사용자에게 전달되는 흐름,

 

하지만 이 패턴의 문제점은 어플리케이션의 규모가 커질수록

데이터 흐름의 복잡도가 무지막지하게 늘어난다는 것이었다.

 

예를 들어 칼럼 게시판을 만든다고 치면.

(이 게시판 UI의 가장 큰 특징은 자신이 최근에 남긴 댓글이 우측 사이드바에 실시간으로 떠오른다.)

 

만일 유저 A가 새 글을 쓰고 유저 B가 댓글을 작성했는데,

 

마음이 바뀐 A가 글을 5분만에 삭제했다면 어떻게 될까?

 

공교롭게도 B가 사이트를 떠나지도 않고 새로고침도 하지 않은 채 창을 내버려뒀다면,

이 게시판은 어떻게 B의 댓글이 지워졌음을 반영할 수 있을까?

게다가, 사이트 헤더에 이 게시판의 전체 댓글 수를 실시간으로 집계하는 카운터가 달려 있다면?

 

Flux 공식 이미지

데이터의 양이 늘어날수록 복잡도가 상당하다.🤯

 

MVC 패턴은 데이터의 변경 사항을 신속하게 전파하기가 어렵다.

모델이 늘어날수록 전파해야 할 대상도 함께 늘어나기 때문이고,

하나의 포스트가 삭제되면 포스트에 딸려 있던 각 댓글도 함께 삭제될 텐데,

이때 댓글을 잃어버린 각 유저의 댓글 사이드바나 사이트 헤더의 전체 덧글 카운터에도 변경사항이 전파되어야 한다.

MVC 패턴에서는 사이드바와 헤더의 데이터를 관리하는 모델들이

포스트 모델을 항상 주시하게 만들게 될 거고 코드는 함께 복잡해질 것이다.

더 커다란 문제는 각 모델에서 발생한 이벤트가 어플리케이션 전체로 무차별적으로 번져나갈 때

어떤 변화가 일어날지 예측할 수가 없다는 데에 있다.

 

 

facebook은 이 문제를 해결하기 위해 flux라는 패턴을 만들었다.

Model이 View를 반영하고, View가 Model을 변경하는 양방향 데이터 흐름에서 벗어나

단방향으로만 데이터를 변경할 수 있도록 만들어 주었다.

 

우선 ‘단방향 데이터 흐름’이 어떻게 이루어지는지를 알아보자.

 

Action / Action Creator

액션은 데이터의 상태를 변경할 수 있는 명령어 카드와 같다.

액션 생성자는 새로 발생한 액션의 타입과 데이터 페이로드를 액션 메시지로 묶어 디스패쳐로 전달시킨다.

 

Dispatcher

디스패쳐는 액션 메시지를 감지하는 순간 그것을 각 스토어에 전달한다.

전달은 콜백 함수로 이루어지며, 등록되어 있는 모든 스토어로 페이로드를 전달할 수 있다.

이때 스토어가 서로를 의존하고 있다면..?

(학생의 개인정보를 담은 스토어와 모든 학생의 수학 점수만을 담은 스토어를 예로 들 수 있겠다.)

특정 스토어가 업데이트되기를 기다리게 해주는 waitFor()를 사용할 수 있다.

 

Store (Model)

스토어는 어플리케이션의 상태와, 상태를 변경할 수 있는 메서드를 가지고 있고,

어떤 타입의 액션이 날아왔느냐에 따라 메서드를 다르게 적용해 상태를 변경하게 된다.

 

View

React에 해당되는 부분이다.

컨트롤러 뷰는 스토어에서 변경된 데이터를 가져와 모든 자식 뷰에게 데이터를 분배한다.

데이터를 넘겨받은 뷰는 화면을 새로 렌더링시킨다.

 

그래서 결과는…

 

  • 선생님이 뷰를 통해 A군의 수학 점수를 입력한다.
  • 뷰는 데이터를 업데이트하기 위해 액션 생성자를 호출한다.
  • 액션 생성자는 수학 점수를 업데이트하기 위한 액션 타입과 입력된 값을 묶어 디스패쳐로 전달한다.
  • (예: actionType: 'UPDATE_MATH', payload: ['A', '75'])
  • 액션 메시지를 감지한 디스패쳐는 액션을 mathStore와 studentStore에 전달한다.
  • 각 스토어는 액션 타입에 따라 상태를 변경한다. 만일 studentStore가 mathStore를 의존하고 있다면, 콜백 체인을 통해 mathStore가 먼저 업데이트되기를 기다렸다가 studentStore를 업데이트할 수 있다.
  • 스토어가 업데이트를 마치면 이를 감지한 컨트롤러 뷰가 자식 뷰에게 새로운 값을 분배한다.
  • 마지막으로 뷰는 새로운 값으로 화면을 렌더링한다.

 

데이터 흐름은 한 방향으로 강제되고,

모든 상태는 스토어에 모여 있으므로 변경 사항을 여러 컴포넌트로 전달하기도 쉬워진다.👍

 

복사했습니다!