-
Notifications
You must be signed in to change notification settings - Fork 0
Description
MobX
Created: December 18, 2021 1:53 PM
Tags: frontend
State Management Library 중 하나
철학
- 쉽다.
- UI framework 밖에서 상태 관리가 가능하다.
- Redux는 React 없이 .. 돌아간다.
- 렌더링 최적화를 쉽게 할 수 있다
- 데이터 모든 변경, 사용을 런타임에 추적
- 상태와 출력 사이 모든 관계를 나타내는 dependency tree를 만들어서, 리액트 컴포넌트처럼 필요한 경우에만 상태에 따라 연산 실행
- Memoization, selector 등을 사용하는 컴포넌트 최적화 작업은 할 필요가 없다.
개념
-
상태(state)
-
동작(action)
-
전파(derivation)
-
상태(
state)를 정의하고observable로 표시해주기State 담기는 데이터 구조는 아무거나 상관 없다. 객체, 배열, 클래스 등...
대신 MobX가 추적할 수 있도록
observable로 표시해줘야 한다. -
action을 이용해서state를 업데이트하기 -
state변경에 자동으로 응답하는derivation만들기-
computed값: 남은 Todo 개수 같이 순수 함수를 사용해서 파생되는 값. -
reaction: 서버에 변경 사항 전송하기 같이 state 변경되면 자동으로 발생되어야 하는 side effect. 그치만 과하게 사용될 수가 있으니 가능한computed쓰기. -
computed쓰는 예시import { makeObservable, observable, computed } from "mobx" class TodoList { todos = [] get unfinishedTodoCount() { return this.todos.filter(todo => !todo.finished).length } constructor(todos) { makeObservable(this, { todos: observable, unfinishedTodoCount: computed }) this.todos = todos } }
-
동작 요약
Uni-directional data flow
import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"
**// State model**
class Timer {
secondsPassed = 0
constructor() {
makeAutoObservable(this)
// makeObservable(this, {
// secondsPassed: observable,
// increase: action,
// reset: action
// }
}
increase() {
this.secondsPassed += 1
}
reset() {
this.secondsPassed = 0
}
}
**// Create the state class instance**
const myTimer = new Timer()
**// Component using the observable state (timer)**
const TimerView = observer(({ timer }) => (
<button onClick={() => timer.reset()}>Seconds passed: {timer.secondsPassed}</button>
))
ReactDOM.render(<TimerView timer={myTimer} />, document.body)
setInterval(() => {
myTimer.increase()
}, 1000)- event:
onClick,setInterval - action:
myTimer.increate,myTimer.reset - update: action 들이 observable state 업데이트
- side-effects: 업데이트가 인지되어 렌더링 실행됨 →
TimerView컴포넌트는timer.secondsPassed에 의존해서 렌더링
참고
-
React 컴포넌트를 감싸는
observer함수는 HOC(Higher-Order Components)함수. 컴포넌트를 감싸서 반응형으로 만들어준다. 렌더링 중에 사용되는 모든 observable에 React 컴포넌트들을 자동으로 구독한다. -
autorun을 사용해서 state가 변경될 때마다 로그를 출력할 수 있다. -
mobx-react-lite패키지는 이름처럼 더 가볍고 함수형 컴포넌트만 지원한다.useContext를 이용해서state를 컴포넌트에 연결한다. -
observer컴포넌트에서 외부 state 사용하려면-
props 사용하기: state 인스턴스를 prop으로 넘기기
-
전역 변수 사용하기 (비추)
-
React context 사용하기
import {observer} from 'mobx-react-lite' import {createContext, useContext} from "react" const TimerContext = createContext<Timer>() const TimerView = observer(() => { // 컨텍스트에서 타이머를 가져옵니다. const timer = useContext(TimerContext) // 위의 타이머 정의를 참고하세요. return ( <span>Seconds passed: {timer.secondsPassed}</span> ) }) ReactDOM.render( <TimerContext.Provider value={new Timer()}> <TimerView /> </TimerContext.Provider>, document.body )
-
-
리액트 컴포넌트는 최소화하기
observer컴포넌트들은 모든 값을 추적하고 변경사항이 있으면 다시 렌더링하기 때문에 작을수록 다시 렌더링해야 하는 변경사항이 적다!
