本文主要讲述如何搭建react+mobx脚手架和mobx的基本用法
一. 搭建脚手架
// 1. 使用create-react-app生成一个项目
create-react-app react-mobx
// 2. 打开依赖配置
cd react-mobx
npm run eject
// 3. 安装插件plugin-proposal-decorators
npm install --save-dev plugin-proposal-decorators
// 4. 配置插件plugin-proposal-decorators,使babel支持装饰器
// package.json
"babel": {
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
],
"presets": [
"react-app"
]
}
// 5. 安装react所需的mobx依赖
npm install --save mobx
npm install --save mobx-react
二. 使用mobx
// 1. 定义store
// TodoListStore.js
import { observable, action, computed } from 'mobx'
class Todo {
id = +new Date(); // <==> new Date().getTime() // 获取时间戳作为唯一id
@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;
}
@action addTodo(title) {
if (!title) {
window.alert('请输入待办任务');
return;
}
this.todos.push(new Todo(title));
}
@action deleteTodo(index) {
this.todos.splice(index, 1);
}
}
const store = new TodoList();
export default store;
// 2. 注册store
// App.js
import React, { Component } from 'react';
import { Provider } from 'mobx-react';
import TodoListStore from './store/TodoListStore';
import TodoList from './components/TodoList/TodoList';
import Other from './components/Other/Other';
import './App.css';
export default class App extends Component {
render() {
return (
<Provider TodoListStore={TodoListStore}>
<div className={'flex'}>
<h1>App</h1>
<TodoList className={'flex-item'} />
<Other className={'flex-item'} />
</div>
</Provider>
)
}
}
// 3. 定义组件(使用store)
// Todo.js
import React from 'react';
import { observer } from 'mobx-react';
const Todo = observer(({todo}) => ( // function组件,使用hooks方便
<li>
<input
type="checkbox"
checked={todo.finished}
onChange={() => { todo.finished = !todo.finished; }}
/>
{todo.title}
</li>
));
export default Todo;
/////////////////////////////////////////////////////////////////////////////////
// TodoList.js
import React from 'react';
import { observer, inject } from 'mobx-react';
import Todo from '../Todo/Todo';
@inject('TodoListStore')
@observer
class TodoList extends React.Component { // 传统的class组件,使用装饰器方便
constructor(props) {
super(props);
this.state = {
title: ''
}
}
handleTitleChange = e => {
let title = e.target.value;
this.setState({ title });
};
handleAdd = () => {
this.props.TodoListStore.addTodo(this.state.title);
};
render() {
const { TodoListStore } = this.props;
return (
<div>
<h3>TodoList</h3>
<input type="text" value={this.state.title} onChange={this.handleTitleChange} />
<button onClick={this.handleAdd}>添加</button>
<ul>
{
TodoListStore.todos.map(todo => (
<Todo todo={todo} key={todo.id} />
))
}
</ul>
已完成任务数: {TodoListStore.completedTodosCount}
</div>
);
}
}
export default TodoList
/////////////////////////////////////////////////////////////////////////////////
// Other.js
import React from 'react';
import { observer, inject } from 'mobx-react';
@inject('TodoListStore')
@observer
class Other extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
return (
<div>
<h3>Other</h3>
<ol>
{
this.props.TodoListStore.todos.map(todo =>
<li key={todo.id}>{todo.title}</li>
)
}
</ol>
</div>
)
}
}
export default Other;
三. 效果演示
- 咋上传不了gif?