redux VS mobx (裝飾器配合使用)

前言:redux和mobx都是狀態管理器,避免父級到子級再到子子級嵌套單向數據流,能夠邏輯清晰的管理更新共享數據。(刷新頁面redux儲蓄數據即消失)
配置使用裝飾器(使用高階函數包裝你的組件):
npm install  babel-plugin-transform-decorators-legacy --save-dev

.babelrc配置:javascript

{
  "presets": [
    "react-app"
  ],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "style": true
      }
    ],
    "transform-decorators-legacy"
  ]
}

當使用react native的時候,下面這個預設能夠代替 transform-decorators-legacyjava

"babel": {
  "presets": [
    "react-app",
    "react-native-stage-0/decorator-support"
  ]
},
一.redux
redux.js文件:
// 定義變量
const CODE_CHANGE = 'CODE_CHANGE'
const NUMBER_LIST = 'NUMBER_LIST'
const ERROR_MSG = 'ERROR_MSG'

// 初始化數據
const initState = {
  industryNumber: storage.get('industryNumber'),
  numberList: [],
  msg: ''
}

// reducer
export function isNumber(state = initState, action) {
  switch (action.type) {
    case CODE_CHANGE:
      return { ...state, industryNumber: action.industryNumber }
    case NUMBER_LIST:
      return { ...state, numberList: action.numberList }
    case ERROR_MSG:
      return { ...state, msg: action.msg }
    default:
      return state
  }
}

reducer.js文件:react

import { combineReducers } from 'redux'
import { isNumber } from '/redux'

export default combineReducers({ isNumber }) // 合併全部的reducer,而且返回

index.js入口文件:git

import React from 'react'
import ReactDOM from 'react-dom'
import MainRouter from './Router'
 // 引入redux
import { createStore, applyMiddleware, compose } from 'redux'
importthunk from 'redux-thunk' // 中間插件,加強dispatch功能,可異步加載action可接受函數參數
import { Provider } from 'react-redux' //redux組件,所有子級能夠直接更新redux的state 
import reducers from './reducer' 
// 這裏判斷瀏覽器環境是否開啓Redux DevTools的插件(chrome瀏覽器擴展插件應用商店下載)
const reduxDevtools = window.devToolsExtension ? window.devToolsExtension() : h => h //沒有插件則返回空函數 
const store = createStore(reducers, compose( applyMiddleware(thunk), reduxDevtools )) // 建立store
ReactDOM.render( 
  <Provider store={store}> 
    <MainRouter/> //路由 
  </Provider>,
  document.getElementById('root')
)

某子組件:github

import { connect } from 'react-redux'  // 裝飾器

const fetchNumberList = () => {
  return dispatch => { // 異步請求須要 dispatch => {}包裹
    fetch('異步請求').then(res => {
      if (res.code === 0) {
        dispatch({ type: 'NUMBER_LIST', numberList: res.data })
      } 
    })
  }
}

@connect(
  state => state.isNumber, // 若是有多個reducer: state => ({ ..state.isNumber, ...state.someName })
  { fetchNumberList }  // 一些以前寫好的action方法
)

class IndustryManagement extends Component {
  constructor(props) {
    super(props)
    this.state= {
      industryNumber: this.props.industryNumber && this.props.industryNumber[0], // 直接props引用redux的state
    }
  }

  btnChange() {
    this.props.fetchNumberList() //通過裝飾器的函數均可用props引用
  }

  render() {
    return (
      <button onClick={ this.btnChange.bind(this) }>
    )
  }  
}

 二. mobxchrome

這裏推薦使用mobx-state-tree的寫法,有興趣的可去github上看用法,如下是傳統寫法:npm

store.js文件:
import { observable, action, runInAction } from 'mobx'
// runInAction接受異步action
class RootStore {
  @observable userInfo = null  //註冊變量並監視變化(能夠是引用類型值或者普通值)

  @observable number1 = 1

  @observable number2 = 2

  @computed getTotal(){
    return this.number1 + this.number2  // 每當監視數據發生變化就會執行@computed
  }
  
  @action.bound getData= async() => { // bound是爲了綁定this上下文(箭頭函數可不須要)
    let res = await get('接口地址')
    if (res.success) {
      runInAction(() => {      // runInAction函數可異步修改@observable數據
        this.userInfo = res.data
      })
    }
  }
}

export default rootStore = new RootStore()

index.js入口文件:redux

import { Provider } from 'mobx-react'  // 與上文的redux的Provider類似
import rootStore from './store'
ReactDOM.render(
  <Provider rootStore={rootStore}>
    <MainRouter />
  </Provider>,
  document.getElementById('root')
)

某子組件:react-native

import { observer, inject } from 'mobx-react'

@inject(({store, otherStore}) => ({ // 選擇注入store(若是有多個store),若是不用inject函數可直接import store from '../store',組件中直接store.userInfo使用
  userInfo: store.userInfo,
  total: store.getTotal
}))

@observer
class EmpRec extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    return(
      <div>
        <div>this.props.userInfo</div>
        <div>this.props.total</div>
      </div>
    )
  } 
}

.瀏覽器

相關文章
相關標籤/搜索