FE MV* (2)

Khan·2023년 2월 6일
0

TIL

목록 보기
17/19

FLUX 패턴

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

등장 배경

  • 대규모 애플리케이션에서 데이터 흐름을 일관성 있게 관리하기 위해서
    • 프로그램에 예측가능성을 높이기 위해
  • MVC 패턴의 단점 (양방향 데이터 흐름)

역할

  • Action
    • Action이란 데이터를 변경하는 행위로서 Dispatcher에게 전달되는 객체
  • Dispatcher
    • Dispatcher는 모든 데이터의 흐름을 관리하는 중앙 허브 역할을 함
    • 주로 switch 문으로 들어오는 Action 객체를 나누어 처리. 미리 정해둔 Action 객체의 type 을 구분해 미리 작성해둔 명령들을 수행.
    • 들어오는 Action 객체 정보를 받아 실제로 어떤 행동을 할지 결정 하는 곳
  • Store (Model)
    • Store는 상태 저장소로서 상태와 상태를 변경할 수 있는 메서드를 가지고 있음
    • Dispatcher에서 콜백함수를 실행 → 상태가 변경 → View에게 데이터가 변경되었음을 알려줌
  • View
    • 새로운 데이터를 받은 View는 화면을 리렌더링합니다.
    • 사용자가 View에 어떤한 조작을 하면 그에 해당하는 Action을 생성합니다.

각 요소들은 단방향 흐름에 따라 순서대로 역할을 수행하고, View로부터 새로운 데이터 변경이 생기면 처음부터 다시 이 순서대로 실행. 이렇게 함으로써 예외 없이 데이터를 처리할 수 있음

예시

  • store
    // store
    const initialState = {
      number: 0
    };
    
    function reducer(state, action) {
      switch (action.type) {
        case 'ADD':
          return {
            number: state.number + 1
          }
        default:
          return state;
      }
    }
  • view
    // view
    function Counter() {
      const [state, dispatch] = useReducer(reducer, initialState)
    
      const onAdd = () => {
        dispatch({type: 'ADD'}) 
      }
      
      return (
        <div>
          <h1>{state.number}</h1>
          <button onClick={onAdd}>Add</button>
        </div>
      )
    }
  • 결과

MVI

배경


사람이 대화할 때 인터페이스 X
컴퓨터와 사람이 대화할 때 인터페이스 O

  • 컴퓨터 관점에서는 함수가 필요
    • user → intent → model → state change → view → user
    • view(model(intent(user())))

역할

View : "User"가 볼 수 있는 화면.

Model : 앱의 유일한 상태와 데이터를 가지고 있는 불변 객체.

Intent : 앱의 상태를 변경하는 요청. (event)

siedEffect : 부수효과 (아직 정의를 못내리겠음)

**Pure cycle**

  • 특징

    • 상태 불변
  • 동작 방식

    • view 업데이트 : intent 이벤트 발생 → 상태 생성 → 상태 적용 → 랜더
  • 장점

    • 상태 불변성으로 예측 가능한 값을 얻을 수 있음
    • 함수형 프로그램에 특징으로서 a()에 b를 넘기면 결과값은 항상 c
    • 테스트 코드 작성 할 때 이점을 보임
  • 코드

// Action (like reducer)
export const _INCREASE = action("_INCREASE")
export const _DECREASE = action("_DECREASE")
export const _RESET = action("_RESET")

// Model
export const store = createStore({count:0}, state => {

  on(_INCREASE, (value) => state.count += value)

  on(_DECREASE, (value) => state.count -= value)

  on(_RESET, () => state.count = 0)
})
// Component
export const App = (props) => {

  // Query
  const count = SELECT(store.count)
  
  // Intent
  const onClick = () => dispatch(_INCREASE(+1))
  
  // View
  return <button onCLick={onClick}>{count}</button>
}
// Component1
const Component1 = (props) => {

  const count = SELECT(store.count)

  return <div>{count}</div>
}

// Component2
const Component2 = (props) => {

  const onClick = () => dispatch(_INCREASE(+1))
  
  return <>
	<Component1/>
    <button onCLick={onClick}>1 증가</button>
  </>
}

**Side effect cycle**

  • 특징
    • intent를 통해 실행되고 결과는 event를 통해 전달

    • 부수 효과를 실행함 (API 호출)

    • model에 새로운 입력값이 될 수 있고 다른 side effect를 발생 시킬수 있음

특징

  • 전체적으로 데이터의 방향성이 단방향으로 연결이 되며 데이터가 전역적으로 구성됨
  • 뷰는 모델에 의존적이지만 비지니스 로직은 뷰와의 의존성이 없기 때문에 화면변화에 유연하며 별도로 테스트를 하기 쉬움
  • 컴포넌트간 데이터 통신에 의존하지 않기 때문에 일관성있는 상태를 유지할 수 있음

0개의 댓글