zoukankan      html  css  js  c++  java
  • redux VS mobx (装饰器配合使用)

    前言:redux和mobx都是状态管理器,避免父级到子级再到子子级嵌套单向数据流,可以逻辑清晰的管理更新共享数据。(刷新页面redux储蓄数据即消失)
    配置使用装饰器(使用高阶函数包装你的组件):
    npm install  babel-plugin-transform-decorators-legacy --save-dev

    .babelrc配置:

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

    当使用react native的时候,下面这个预设可以代替 transform-decorators-legacy

    "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文件:

    import { combineReducers } from 'redux'
    import { isNumber } from '/redux'
    
    export default combineReducers({ isNumber }) // 合并所有的reducer,并且返回

    index.js入口文件:

    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')
    )

    某子组件:

    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) }>
        )
      }  
    }

     二. mobx

    这里推荐使用mobx-state-tree的写法,有兴趣的可去github上看用法,以下是传统写法:

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

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

    某子组件:

    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>
        )
      } 
    }

    .

  • 相关阅读:
    天气预报APP(2)
    天气预报APP(1)
    android ——网络编程
    android ——Intent
    android ——可折叠式标题栏
    5.1 类,实例,实现,方法
    5.0 面向对象
    python 基础
    模拟实现一个ATM + 购物商城程序
    python 基础
  • 原文地址:https://www.cnblogs.com/crazycode2/p/9420539.html
Copyright © 2011-2022 走看看