这边文章主要目的呢。是搭建一个react和mobx的demo。可以了解mobx在react应用中如何使用的。我会用大白话的形式写这个文章; 文末有react 和react-native 的两个集成mobx的项目demo。react-native的实现思路和下面同样。react
#####1.create-react-app建立react项目 脚手架命令生成一个项目:webpack
1.create-react-app react_mobx
//建立好脚手架安装mobx和mobx-react 包
2. npm install mobx mobx-react --save
3. npm install react-router --save
复制代码
安装好上面依赖。咱们修改下项目结构----你们能够自行修改下; git
#####2.实现react-router功能 你们都知道mobx能够解跨页面共享数据的问题。那咱们先实现跳转页面功能;咱们先修改下下面几个文件-- 1.home.jsx
github
import React, { Component } from "react";
class Home extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<h1>首页</h1>
<button onClick={() => { this.props.history.push("/one");}}>
跳转到第一个页面
</button>
</div>
);
}
}
export default Home
复制代码
2.one.jsx
web
import React, { Component } from "react";
class One extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<h1>页面一</h1>
<button onClick={() => { this.props.history.push("/");}}>
跳转到首页
</button>
</div>
);
}
}
export default One
复制代码
3.router.jsx
npm
import React, { Component, Fragment } from "react";
import { HashRouter,Route } from "react-router-dom";
import Home from '../page/home';
import One from '../page/one';
class Router extends Component {
render() {
return (
<HashRouter>
<Fragment>
<Route exact path={`/`} component={Home} />
<Route path={`/one`} component={One} />
</Fragment>
</HashRouter>
);
}
}
export default Router;
复制代码
4.index.js 文件入口
redux
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router/router';
ReactDOM.render(<Router />, document.getElementById('root'));
复制代码
好了文件修改完毕~ npm start
一下,页面是否是能够自由跳转了呢~ 好了 实现了这个咱们就进行下一步吧react-native
重要提醒--MobX采用的是ES7的装饰器语法,目前仍是一种实验性的语法,使用 create-react-app 脚手架默认建立的项目是没有开启装饰器语法的。须要一些额外的配置查看下这篇文章:
create-react-app配置修饰器 可能这个方法比较麻烦-----我如今解决方案是这个--有好的办法 我会及时更新的~bash
#####3.mobx和mobx-react的使用 3.1须要项目结构src下增长一个store文件夹 --这个文件夹的做用。咱们理解为专门存放和管理数据源的地方; react-router
建立3个js文件- homeStore.js、oneStore.js、index.js 下面对每一个文件夹进行添加代码 homeStore.js: 存放一个页面数据源的类
import { observable} from "mobx";
class HomeStore {
@observable homeNum = 0;
}
export default HomeStore;
复制代码
oneStore.js: 存放一个页面数据源的类
import { observable} from "mobx";
class OneStore {
@observable oneNum = 3333;
}
export default OneStore;
复制代码
index.js: 将多个store融合到一个对象里面
import HomeStore from "./homeStore";
import OneStore from "./oneStore";
let oneStore = new OneStore();
let homeStore = new HomeStore();
const stores = {
oneStore,
homeStore
};
/// 默认导出接口
export default stores;
复制代码
这些文件夹建立的意义是什么呢。其实一个xxxStore的话 就是一个数据源的地方。每一个类里面能够定义咱们须要用到的数据-就和咱们react中state同样;index.js的做用呢 就是把全部数据整合到一块去-- 其实也是为了下面一部作铺垫的;
3.2 项目入口index.js部分代码修改 index.js
import React from "react";
import ReactDOM from "react-dom";
import Router from "./router/router";
import { Provider } from "mobx-react";
import stores from "./store";
ReactDOM.render(
<Provider {...stores}>
<Router />
</Provider>,
document.getElementById("root")
);
复制代码
这边咱们引入 Provider 和上面说起到的store 。这边其实就是一个数据容器,也是mobx这一类数据流框架实现数据共享的基础。
咱们子组件放在这个数据容器当中。mobx才能够作到跨组件数据共享Provider 这个其实不陌生了。其实就是react中context 中的属性--本身写的关于react Context的文章 不了解的同窗能够学习一下。
3.3 page/home.jsx 的代码修改 既然Provider是数据容器。咱们子组件在容器里面。那咱们子组件是如何使用容器里面的数据呢--看一下下面代码
import React, { Component } from "react";
+ import { observer, inject } from "mobx-react";
+ @inject("homeStore")
+ @observer
class Home extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
+ <h1>首页数据源的number为:{this.props.homeStore.homeNum}</h1>
<button onClick={() => { this.props.history.push("/one") }}>
跳转到第一个页面
</button>
</div>
);
}
}
export default Home;
复制代码
代码中+
就是新添加的代码 。下面介绍一下咱们用到的几个熟悉吧 observer:
将你的组件变成响应式组件。就是数据改变时候能够出发从新的渲染。 inject(homeStore):
和redux的connect做用同样,将数据注册到组件。homeStore其实就咱们store/index中 new出来的实例名称; this.props.homeStore.xxx
:这个就是如何使用数据源中的值.就和组件透传同样
3.4 数据源如何修改? 既然上文咱们实现了数据的展现,那么固然少不了操做数据的操做-咱们就进行下一个操做 @action:
请求的意思-在严格模式下。这是惟一操做store的操做; +表明新增代码
修改数据源
//homeStore.js
import { observable,action} from "mobx";
class HomeStore {
@observable homeNum = 0;
+ @action addNum() {
+ this.homeNum += 1;
+ }
+ @action lessNum() {
+ this.homeNum -= 1;
+ }
}
export default HomeStore;
复制代码
展现增长操做按钮
store里面定义的@action这边就用this.props.home.addNum()
操做就能够了render() {
return (
//代码自行添加。。。。。。
+ <div>
+ <h1>首页数据源的number为:{this.props.homeStore.homeNum}</h1>
+ <button onClick={() => {this.props.homeStore.addNum()}} >
+ 点击添加
+ </button>
+ <button onClick={() => {this.props.homeStore.lessNum()}}>
+ 点击删除
+ </button>
+ </div>
//代码自行添加。。。。。。
);
}
}
export default Home;
复制代码
3.5 共享的数据怎么使用? 展现和修改的操做都完成了--那么咱们下一步应该是mobx共享数据了。如何实现数据共享呢。其实很简单 咱们直接看代码-在咱们须要用到的数据源页面上加上@inject("homeStore")
就能够了---固然修改共享数据 也是
import React, { Component } from "react";
import { observer, inject } from "mobx-react";
@inject("homeStore")
@inject("oneStore")
@observer
class One extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<h1>页面一</h1>
<h1>首页数据源的number为:{this.props.homeStore.homeNum}</h1>
<h1>oneStore的number为:{this.props.oneStore.oneNum}</h1>
<button onClick={() => { this.props.history.push("/");}}>
跳转到首页
</button>
</div>
);
}
}
export default One
复制代码
去第二个页面查看一下数据展现:
这样一套流程结束啦~
#####4.严格模式的设置 若是咱们不适用严格模式的话。你能够有这么一个骚操做;在页面中使用下放代码:
this.props.homeStore.homeNum = 33;
复制代码
你会发现你的数据源数据被修改过了~很方便对吧。but这是很危险的操做
数据源就变得不可追溯了~ 那么如何设置的-也是很简单的啦~ 项目入口index.js
+ import { configure } from "mobx";
//代码自行增长
render(
<div>
<Provider {...stores}>
<XXX />
</Provider>
</div>,
document.getElementById("root")
);
//5.x版本严格模式开启方式
+ configure({
+ enforceActions: "observed"
+ });
复制代码
这样开启严格模式就能够了---这样的好处呢就是操做数据源的惟一操做就是经过action。数据流变得可追溯了~
todo:代码仍是有不少须要优化的地方 1.@observer不能放置在export default前 2.对于create-react-react 修饰器的支持感受有点麻烦了
好了文章处处结束了; 写的比较简单。若是有写的不对的地方欢迎指正-- 下面给一下git地址-- 本身写了2个demo 一个是本身手动搭建webpack的demo 一个是脚手架生成的demo 本身手动webpack-mobx项目 create-react-app项目 react-native 集成mobx项目