July 03, 2021
현재 진행중인 프로젝트에서 React의 상태관리 라이브러리로 Mobx를 쓰고 있는데, 어떻게 Mobx가 상태관리를 하는지 알아보고 내부 공유용으로 발표하기 위해 정리해보았다.
6버전을 바탕으로 정리합니다. 5버전 이상부터는 Proxy를 쓰기 때문에 IE에서 지원이 되지 않습니다. 단 6버전에서 옵션을 통해 IE를 지원할 수 있습니다.
import { configure } from "mobx"
configure({ useProxies: "never" }} // Proxy를 사용하지 않음
하나 이상의 사용자 인터페이스 컨트롤의 상태를 관리한다.
라고 정의를 하고 있다. 사용자가 어떠한 행위를 통해 파생되어 값이 바뀌게 될텐데, 이러한 값을 관리하거나 바뀐 것을 인지하고 뷰에 보여주는 모든 것을 관리하는 것이라 생각한다.Class
일 필요는 없다.Mobx에서 가장 중요한 어노테이션은 세가지로 정의할 수 있다.
observable
: 상태를 저장, 추적 가능한 값(필드)를 스토어에 정의 할 수 있다.action
: 해당 메소드는 상태 값을 바꿀 수 있다는 것을 정의함.computed
: 파생되어서 새롭게 만들어지는 값을 getter할수 있게 정의함.이 중에서 observable
이 어떻게 값을 바꾼것을 알고 update, rerender 하는지 깊게 알아보자.
Store
Class를 생성시 Contructor에서 makeObservable()
을 통해 해당 속성이 관찰 해야하는 값인지를 명시해준다. extends 하는 값이 없다면 makeAutoObsevable()
을 사용해서 자동으로 값과 메서드를 관찰가능한
상태로 만들 수 있다.
value
는 observable, 메서드인 increase()
는 action으로 구분짓는다.observable
을 등록하는 방법은 세가지가 있다.makeObservable
/ makeAutoObservable
/ observable
make(Auto)Observable
은 인자로 들어온 객체를 바로 변경하지만, observable
의 경우 객체를 복제본을 만든다.Proxy
var obj = {}
var newObj = {
get: function (obj, name) {
return name in obj ? obj[name] : undefined
},
set: function(obj, property, value) {
obj[property] = value
}
}
var proxy = new Proxy(obj, newObj)
proxy.a = 10
proxy.b = 11
console.log(proxy.a) // 10
console.log(proxy.dd) // undefined
console.log(obj.a) // 10
console.log(obj == proxy) // false
console.log(typeof proxy) // object
makeObservable()을 통해 관찰할 대상을 명시한다. 내부 함수를 보자.
var $mobx = /*#__PURE__*/Symbol("mobx administration");
makeObservable은 첫번째 인자로 this를 받으며(객체 자신), 두번째 인자로 객체를 받는데, 관찰할 대상의 속성, 메서드, 클래스 필드명은 키로 가지면서 값으로는 mobx 내장 함수를 받는다.
내부에서, 중복되는 observable
값인지 검증하고, 등록이 되지 않은 값들만 관찰할 수 있게 등록을 한다.
makeObservable()
함수를 통해서 받은 값을 관찰 할수 있는 option들이 달린ObservableObjectAdministration
symbol값과 부수적인 함수들을 추가해서 해당 값들을 관리한다. 마지막으로는 this를 관찰가능한 값으로 수정해서 리턴해준다.
console.log(store)
를 보면 makeObservable()
함수를 통해서 받은 값을 관찰 할수 있는 option들이 달린target_ : ObservableObjectAdministration
symbol이 추가되어 있다.Mobx의 observable은 createObservable()
과 observableFactory
가 합쳐진 객체이다.
observable.box에서는 ObservableValue로 리턴을 해주는데, 해당 observableValue의 중요한 Set만을 보자.
Mobx 내부에서 값이 바뀌었다고 해서, React가 다시 화면을 그리진 않는다.
mobx-react
에서 제공하는 observer(Component)
로 컴포넌트를 래핑한다.(내부적으로 쓰고 있기 때문에), 공식문서에서도 memo를 쓸 필요가 없다고 한다. memo를 통해 해당 컴포넌트를 다시 그릴지 할지 결정된다.
observable
한 값을 만들기 위해 makeObservable()
을 통해 생성, 등록한다.makeObservable()
을 통해 만들어진 스토어는 내부에 관찰할 대상 객체의 키, 밸류 뿐만 아니라 ObservableObjectAdministration
Symbol 값을 가지고 있다. 고유한 이름 부터, 관찰 등록할 naming, 안에서 스토어의 값을 get
, set
할때 intercept
하는 로직이 있다.mobx-react
의 observer()
로 래핑한 컴포넌트가 값이 바뀌었다는 것을 인지하고 다시 그려준다.computed
,action
부분도 비슷한 원리겠지만 깊게 한번 봐야겠다.