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>this.props.userInfo</div>
          <div>this.props.total</div> // 3
    )
    }
    }

     对比下来感觉mobx比redux好用(逃~)

  • 相关阅读:
    个人笔记 给hover 伪类 恢复默认值
    vue 正则判断
    音乐播放器封装
    jq封装插件,简单dome
    功能齐全轮播
    vue 前端判断输入框不能输入0 空格。特殊符号。
    jq 下拉框
    IPC : 进程间通信方式
    内存
    const char* str 与char str[10]
  • 原文地址:https://www.cnblogs.com/xiaoxiao666/p/8873552.html
Copyright © 2011-2022 走看看