mobx在react如何使用?3分鐘學會!

這邊文章主要目的呢。是搭建一個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.jsxgithub

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.jsxweb

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.jsxnpm

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

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項目

相關文章
相關標籤/搜索