mobx在react中的应用(1)

917 阅读2分钟

本文主要讲述如何搭建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?

四. 源代码

github.com/coderben201…