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

小人頭發表於2020-01-08

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

自己無聊寫的小程式 歡迎提bug

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

相關文章