MobX用于简单、可扩展的React状态管理,相比Redux有更高的灵活性,文档参考:MobX中文文档,本文作为入门,介绍一个简单的TodoList
项目。
1. 预期效果
项目机构:
2. 项目搭建
- Step1:
npx create-react-app my-app
创建项目; - Step2:
npm install mobx mobx-react --save-dev
安装 mobx 的相关依赖; - Step3:
npm run eject
使create-react-app 创建的项目支持装饰器语法; - Step4:
npm install @babel/plugin-proposal-decorators --save-dev
安装装饰器 - Step5: 修改
package.json
文件:
"babel": {
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
],
"presets": [
"react-app"
]
},
3. 创建TodoListStore
Mobx 中创建 store 的常见关键字如下: observable
, computed
, action
。
import { observable, action, computed } from 'mobx'
class Todo {
id = Math.random();
@observable title;
@observable finished = false;
constructor(title) {
this.title = title
}
}
class TodoList {
@observable todos = [];
@computed get completedTodosCount() {
return this.todos.filter(todo => todo.finished).length;
}
@computed get report() {
if (this.todos.length === 0)
return "任务已完成"
return `下一个任务:${this.todos[0].title}`
}
@action addTodo (title) {
if (!title) return;
this.todos.push(new Todo(title));
}
}
const store = new TodoList();
store.todos.push(new Todo('修复谷歌浏览器页面显示问题'), new Todo('提交意见反馈代码'));
store.todos[1].finished = true;
export default store;
4. 创建TodoListView
import React, {Component} from 'react';
import {observer, inject} from 'mobx-react';
const TodoView = ({todo}) => (
<li>
<input
type="checkbox"
checked={todo.finished}
onChange={() => {todo.finished = !todo.finished;}}
/>
{todo.title}
</li>
)
@inject('TodoListStore')
@observer
class TodoListView extends Component {
constructor(props) {
super(props);
this.state = {
title: ''
}
}
changeTitle = e => {
let title = e.target.value;
this.setState({title});
}
submit = () => {
this.props.TodoListStore.addTodo(this.state.title);
}
render() {
return (
<div>
<input type="text" value={this.state.title} onChange={this.changeTitle} />
<button onClick={this.submit}>submit</button>
<ul>
{this.props.TodoListStore.todos.map(todo => (
<TodoView todo={todo} key={todo.id} />
))}
</ul>
Tasks finished: {this.props.TodoListStore.completedTodosCount}
</div>
);
}
}
export default TodoListView
5. 在App.js中引入TodoListView
import React, { Component } from 'react';
import './App.css';
import TodoListStore from "./components/todolist/store/TodoListStore";
import TodoListView from "./components/todolist/index";
import { Provider } from 'mobx-react';
export default class App extends Component {
render() {
return (
<Provider TodoListStore={TodoListStore}>
<TodoListView/>
</Provider>
)
}
}
6. 主入口文件src/index.js设置
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App/>, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。