mobx在react如何使用?3分钟学会!

这边文章主要目的呢。是搭建一个react和mobx的demo。能够了解mobx在react应用中如何使用的。我会用大白话的形式写这个文章;
文末有react 和react-native 的两个集成mobx的项目demo。react-native的实现思路和下面一样。

1.create-react-app创建react项目

脚手架命令生成一个项目:

1.create-react-app react_mobx
//创建好脚手架安装mobx和mobx-react 包
2. npm install mobx mobx-react --save
3. npm install react-router --save

安装好上面依赖。我们修改下项目结构----大家可以自行修改下;


项目结构
2.实现react-router功能

大家都知道mobx可以解跨页面共享数据的问题。那我们先实现跳转页面功能;我们先修改下下面几个文件--
1.home.jsx

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

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

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 文件入口

import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router/router';
ReactDOM.render(<Router />, document.getElementById('root'));

好了文件修改完毕~ npm start 一下,页面是不是可以自由跳转了呢~ 好了 实现了这个我们就进行下一步吧

重要提醒--MobX采用的是ES7的装饰器语法,目前还是一种实验性的语法,使用 create-react-app 脚手架默认创建的项目是没有开启装饰器语法的。需要一些额外的配置查看下这篇文章:create-react-app配置修饰器
可能这个方法比较麻烦-----我现在解决方案是这个--有好的办法 我会及时更新的~

3.mobx和mobx-react的使用

3.1需要项目结构src下增加一个store文件夹
--这个文件夹的作用。我们理解为专门存放和管理数据源的地方;

store的放置位置

创建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:这个就是如何使用数据源中的值.就和组件透传一样

image.png

3.4 数据源如何修改?
既然上文我们实现了数据的展示,那么当然少不了操作数据的操作-我们就进行下一个操作
@action:请求的意思-在严格模式下。这是唯一操作store的操作;
+代表新增代码

  • 修改store/homeStore.js 修改数据源
//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;
  • 修改page/home.jsx 展示增加操作按钮 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项目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • [toc] REACT react :1.用来构建用户界面的 JAVASCRIPT 库2.react 专注于视图层...
    拨开云雾0521阅读 1,428评论 0 1
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,804评论 0 24
  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,419评论 1 33
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,809评论 1 18
  • 说在前面 关于 react 的总结过去半年就一直碎碎念着要搞起来,各(wo)种(tai)原(lan)因(le)。心...
    陈嘻嘻啊阅读 6,846评论 7 41