什麼是Mobx
MobX 是一個經過戰火洗禮的庫,
它通過透明的函式響應式程式設計
(transparently applying functional reactive programming - TFRP)
使得狀態管理變得簡單和可擴充套件。
複製程式碼
更多詳細介紹,請移步官網細閱。
為什麼使用Mobx
React 和 MobX 是一對強力組合。React 通過提供機制把應用狀態轉換為可渲染元件樹並對其進行渲染。而MobX提供機制來儲存和更新應用狀態供 React 使用。 ——官方文件
可能我們都比較熟悉Redux,簡而言之Mobx是比Redux更有力的和React結合使用的助手。
如何使用
下面我們就用一個例子簡單的使用Mobx——ToDOList. Talking is cheap, show me your code! 程式碼地址 由於沒有和parcel使用初探的程式碼分離,所以,希望你也能看的明白
編輯器
VSCode
編輯器配置
為了使用Es.next的裝飾器語言@,需要配置VsCode,具體——如何(不)使用裝飾器
依賴
//package.json file setup:
"dependencies": {
"mobx": "^3.4.1",
"mobx-react": "^4.3.5",
"react": "^16.2.0",
"react-dom": "^16.2.0"
}
複製程式碼
//package.json file setup:
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-1": "^6.24.1",
"mobx-react-devtools": "^4.2.15",
}
複製程式碼
配置
//.babelrc file setup:
{
"presets": [
"env",
"react",
"es2015",
"stage-1"
],
"plugins": [
"transform-decorators-legacy"
]
}
複製程式碼
程式碼
store 建立
import { observable, autorun, computed, action } from 'mobx';
class toDo {
id = Math.random();
@observable title = '';
@observable completed = false;
}
class todoStore {
@observable todos = [];
@computed get completedCount() {
return this.todos.filter(todo => todo.completed).length;
}
@computed get totalCount() {
return this.todos.length;
}
@action.bound toggleCompleted(id) {
this.todos.forEach(todo => {
if (todo.id === id) todo.completed = !todo.completed;
})
}
@action.bound addToDo(title) {
if (!title) return alert('please input something...');
let todo = new toDo();
todo.title = title;
this.todos.push(todo);
}
};
const store = new todoStore();
export { store }
複製程式碼
ToDo元件
import React, { Component } from 'react';
import { observer } from "mobx-react";
import { store } from '../../store'
import './style.css'
@observer export default class ToDo extends Component {
constructor(props) {
super(props);
}
render() {
const { title, id, completed } = this.props;
return (<div
className={`todo ${completed ? 'completed' : ''}`}
onClick={() => store.toggleCompleted(id)}
>
{title}
</div>);
}
}
//style.css
.todo{
background-color: white;
text-align: center;
font-size: 30px;
margin: 3px;
}
.todo.completed{
background-color: brown;
}
複製程式碼
App.js
import React, { Component } from 'react'
import { observer } from "mobx-react";
import DevTools from 'mobx-react-devtools'
import ToDo from './components/ToDo'
import { store } from './store'
const TEXT = 'please input something...';
const ToDoList = ({ todos }) => todos.map(t => <ToDo key={t.id} {...t} />);
@observer export default class App extends Component {
constructor(props) {
super(props);
this.state = {
title: ''
}
}
render() {
const { title } = this.state;
const { todos, totalCount, completedCount } = store;
return (<div className="APP">
<input
style={{ width: 300 }}
placeholder={TEXT}
value={title}
onChange={e => this.setState({ title: e.currentTarget.value })}
/>
<button onClick={() => {
store.addToDo(title);
this.setState({ title: '' });
}}>Add one ToDo</button>
<div>{`total count:${totalCount}`}</div>
<div>{`total completed count:${completedCount}`}</div>
<ToDoList todos={todos} />
<DevTools />
</div>);
}
}
複製程式碼