191031 TIL MobX todo
Oct 31, 2019
»
1.5막,
TIL (Today I Learned)
오늘 할 일
- 벨로퍼트 MobX 씹어먹기
- MobX & React로 뭐 만들어보기
observable
Usage:
observable(value)
@observable classProperty = value
예시:
const calculator = observable({
a: 1,
b: 2
})
reaction
Usage:
reaction(() => data, (data, reaction) => { sideEffect }, options?)
예시:
reaction(
() => calculator.a,
(value, reaction) => {
console.log(`a 값이 ${value} 로 바뀌었네요!`);
}
);
computed
예시:
const sum = computed(() => {
console.log('calculating...');
return calculator.a + calculator.b;
})
observe
usage: observe(target, propertyName?, listener, invokeImmediately?)
예시
const person = observable({
firstName: "soom",
lastName: "Shin"
})
const disposer = observe(person, change => {
console.log(change.type, change.name, "from", change.oldValue, 'to', change.object[change.name])
});
person.firstName = "soomin"
disposer();
//update firstName from soom to soomin
autorun
reaction이나 computed의 observe대신 쓸 수 있음.
autorun에 전달해주는 함수에서 사용되는 값이 있으면 자동으로 그 값을 주시하여 그 값이 바뀔때마다 함수 주시됨.
computed로 만든 값의 .get() 함수를 호출해주면 observe 하나하나 안 달아줘도 됨.
설명 출처는 벨로퍼트님
공식사이트에 아주 좋은 이미지가 있어서 가져옴…
리액트로 todo 만들었던거 MobX써서 수정해보려고 하는데, 어디까지 빼도 되는지 구분이 잘 안되네…
ContextAPI -> MobX로 바꾸기
처음부터 아예 만들어보려고 했는데 너무 삽질이 큰 거 같아서 기존에 강의 보고 만든 걸 MobX로 바꿔보았다.
먼저 한 것
1. mobx, mobx-react 설치 및 decorator 추가
yarn add mobx mobx-react
yarn add --dev customize-cra react-app-rewired @babel/plugin-proposal-decorators
//package.json
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
},
// root에 config-overrides.js 파일 생성
const { override, addDecoratorsLegacy } = require('customize-cra')
// Adds legacy decorator support to the Webpack configuration.
module.exports = override(addDecoratorsLegacy())
2. store 생성 및 연결
//src > stores > todo.js
import { observable, action, computed } from 'mobx';
export default class todoStore {
// 기존 context파일에 initialTodos 가져옴
@observable todoList = [
{ id: 1, text: '프로젝트 생성하기', done: true },
{ id: 2, text: '밥먹기', done: true },
{ id: 3, text: '기능구현하기', done: false },
{ id: 4, text: '커피마시기', done: false }
];
}
// index.js
import { Provider } from 'mobx-react';
import TodoStore from './stores/todo';
const todo = new TodoStore();
ReactDOM.render(
<Provider todo={todo}>
<App/>
</Provider>, document.getElementById('root')
);
//Todohead.js
import { inject, observer } from 'mobx-react';
const TodoHead = ({ todos }) => {
// 기존의 state에서 가져오던 todos를 props로 넘겨줌
// const todos = useTodoState();
const undoneTasks = todos.filter(todo => !todo.done);
return (
<TodoHeadBlock>
<div className="tasks-left">할 일 {undoneTasks.length}개 남았당!</div>
</TodoHeadBlock>
)
}
// 여기서 TodoList 주입
export default inject(({ todo }) => ({
todos: todo.todoList,
}))(observer(TodoHead));
3. dispatch로 전달하던 함수들 store로 이동 및 연결
//store
@action
toggle = id => {
const item = this.todoList.find(item => item.id === id);
item.done = !item.done;
};
//Todoitem.js
const TodoItems = observer(({ item, onToggle, onRemove}) => {
// 기존 dispatch로 넘겨주던 함수를 props로 받아옴
/* const dispatch = useTodoDispatch();
const onToggle = () => dispatch({ type: 'TOGGLE', id }); */
return (
<TodoItemBlock>
<CheckCircle done={item.done} onClick={() => onToggle(item.id)}>
{item.done && <MdDone/>}
</CheckCircle>
<Text done={item.done}> {item.text} </Text>
<Remove onClick={() => onRemove(item.id)}>
<MdDelete/>
</Remove>
</TodoItemBlock>
);
});
contextAPI를 꺼도 작동 잘하면 문제 없긔~
- hooks 쓴 MobX 자료가 너무 없어서 어제 헤맸는데, hooks가 ... 필요 없어서 자료가 없는건가?
- 아니, MobX 쓰면 리액트 배운걸 써먹을 데가 별로 없겠는걸? (아니겠지?)