MobX는 기본적으로 상태(state)가 있고, 이 state를 observable이라는 객체로 감싸주면 state가 바뀔 때마다 observer들에게 바뀐 상태에 대해 알려준다. 리덕스에 비해 엄청 간단하다.
MobX는 리덕스보다 간단하지만 너무 자유롭기 때문에 프로젝트를 함께 협업해서 만들어나가는 입장에서 정해진 틀이 없이 우후죽순으로 개발될 가능성이 크다. 따라서 초기 틀을 잘 잡고 해당 틀 내에서 개발하는 것이 중요함
index.js
const { observable, autorun, runInAction } = require("mobx");
// 1. initialState
const state = observable({
compA: "a",
compB: 12,
compC: null,
});
// 2. subscribe autorun은 바뀐 것을 감지해주는 역할을 한다.
autorun(() => {
console.log("changed", state.compA);
});
// 4. event binding 하나의 액션 안에 여러 이벤트를 담을 수 있다.
runInAction(() => {
state.compA = "b"; // 3. dispatch 값을 직접 바꿔주면 dispatch 된다.
state.comC = "1212";
});
runInAction(() => {
state.compA = "b"; // 5. 같은 값 할당 ?
});
runInAction(() => {
state.compA = "c";
});
// changed b
// changed c
observable
로 객체를 감싸주면 끝임 (물론 다양한 방식이 있지만 제일 간단함)runInAction
이라는 함수에 분리해서 담아놓으면 된다.추가적으로 action
과 reaction
이라는 메서드도 지원이 된다.
const { observable, autorun, reaction, action, runInAction } = require("mobx");
const state = observable({
compA: "a",
compB: 12,
compC: null,
});
reaction(
() => {
return state.compB; // 1. reactions: 특정 state 변경 감지
},
() => {
console.log("reaction:", state.compB);
}
);
const change = action(() => {
state.compA = 1;
});
change();
runInAction(() => {
state.compB = 2; // reaction: 2
state.compC = "c";
});
리덕스에서는 state를 하나의 객체로 묶어야 한다.
그러나 mobX는 여러개의 객체를 가질 수 있다. 또한 데이터를 직접 변경해도 immer가 자동 적용된다.
// 여러 개의 state를 가질 수 있다.
const userState = observable({
isLoggingIn: true,
data: null,
});
const postState = observable([]);
// 직접 데이터를 변경해준다.
postState.push({ id: 1, content: "aa" });
userState.data = { id: 1, nickname: "vicky" };
리덕스는 하나의 액션에 여러가지 이벤트를 동시에 실행시킬 수 있을까? 예를 들어 로그인을 하면서, 게시글을 동시에 등록한다고 한다면..? 리덕스로는 어렵다. 왜냐면 리듀서 사이를 분리해놓았기 때문에 넘나드는게 한계가 있기 때문. 하지만 mobX는 가능하며 자유롭다. (리덕스로 구현하려면 액션을 두 개 생성해서 같이 실행해주는 방법 밖에 없다.)