乐趣区

关于前端:React-状态管理对比

源码:地址

在应用 React 过程中应用状态治理的抉择切实是太多,这里只找这三种尝试比照

  • React Redux
  • Mobx
  • dva

React Redux

官网

单项数据流治理

须要下载依赖

yarn add redux react-redux redux-thunk

Provider

通过 Provider 组件来包裹 app 能够使得全局来拜访咱们的 store

import {Provider} from 'react-redux'
import store from './store'
...
ReactDOM.render(<Provider store={store}>
    <App />
  </Provider>,
  rootElement
)

connect

connect 连贯组件和状态治理

import {connect} from 'react-redux'
import {addCount} from './store/redux'

// ReduxDemo 组件

const mapStateToProps = state => {
  return {num: state.num.count}
}

const mapDispatchToProps = dispatch => ({add() {dispatch(addCount())
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(ReduxDemo)

store 套路

  • 定义常量
  • 定义 actions
  • 编写 reducer
  • 创立 store
import {createStore, compose, applyMiddleware, combineReducers} from 'redux'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// 常量
export const ADD = 'demo/add_conut'

// actions
export const changeCount = ({count}) => ({
  count,
  type: ADD
})
export const addCount = () => {return (dispatch, getState) => {let _state = getState()
    _state.num.count++;
    dispatch(changeCount(_state.num))
  }
}
// reducer
const defaultState = {count: 0}

const reducer = (state = defaultState, action) => {switch (action.type) {
    case ADD:
      return Object.assign({}, state, { count: action.count});
    default:
      return state;
  }
}
// store
export default createStore(
  // 模块化 reducer
  combineReducers({num: reducer // store 中能够定义不同模块}),
  composeEnhancers(applyMiddleware(thunk)
  )
);

Mobx

文档

双向数据流绑定

装置依赖

yarn add mobx mobx-react

Mobx 创立 store 绝对简略

store 的不同的形式

  • 对象形式
import {observable, action, computed, makeAutoObservable, makeObservable} from 'mobx';

// 对象
const store = makeObservable(
  {
    count: 0,
    get double() {return this.count * 2;},
    addCount() {this.count += 1;},
    subCount() {this.count -= 1;}
  },
  // 对属性进行包装,用于标记属性的作用
  {
    count: observable, // 响应属性
    double: computed, // 计算属性
    addCount: action, // action 办法,扭转响应属性
    subCount: action
  }
)

export default store

makeObservable 能够创立一个响应式对象,与 Vue 3.0 相似,传入的对象属性也是通过 Proxy 代理

makeAutoObservable 则更弱小,能够主动为对象属性包装函数

import {makeAutoObservable} from 'mobx';

// 对象
const store = makeAutoObservable(
  {
    count: 0,
    get double() {return this.count * 2;},
    addCount() {this.count += 1;},
    subCount() {this.count -= 1;}
  }
)
  • 类形式
class Store {constructor() {makeAutoObservable(this)
  }
  count = 0
  get double() {return this.count * 2;}
  addCount() {this.count += 1;}
  subCount() {this.count -= 1;}
}
export default new Store()

注入 store 与连贯组件

App.js 中注入 store

import {Provider} from 'mobx-react'
import store from './store/mobx';
import Mobx from './Mobx.jsx';

const App = () => {
  return (
    <div>
      <Provider store={store}>
        <Mobx />
      </Provider>
    </div>
  )
}

这里的 Provider 组件中的 propsstore,它是能够任由咱们自定义的,而在组件中连贯须要传入这个 props 变量名

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

function MobxDemo({store}) {
  return (
    <div>
      <h2>Mobx</h2>
      <p> 点击数:{store.count}</p>
      <p> 计算属性单数:{store.double}</p>
      <button onClick={() => store.addCount()}> 点击 +</button>
      <button onClick={() => store.subCount()}> 点击 -</button>
    </div>
  )
}

export default inject('store')(observer(MobxDemo));

组件通过 inject 注入咱们须要传入的 store,组件通过 props.store 属性拜访

dva

文档

dva 是一个的 React 利用框架,简化 API,让开发 React 利用更加不便和快捷。

dva = React-Router + Redux + Redux-saga

依赖装置

yarn add dva

应用

须要实例化 dva

import React from 'react'
import dva, {connect} from 'dva';
import dvaModel from './store/dva';
import DvaDemo from './Dva.jsx'

const createHistory = require("history").createHashHistory

const history = createHistory()

// 创立利用
const app = dva({history: createHistory()
});
app.model(dvaModel)
// 注册视图
app.router(() => <DvaDemo />);
// 启动利用
app.start('#app');

model

创立一个 model 数据,根本的属性

  • namespace 空间命名,全局惟一
  • state 初始数据
  • reducers 批改数据,相似 vuex 中的 mutations
  • effects 获取数据, 相似 vuex 中的 action
  • subscription 订阅数据
const model = {
  namespace: 'dvamodel',
  state: {
    name: 'model dva',
    count: 0
  },
  reducers: {add(state) {
      state.count = state.count + 1
      return {...state}
    },
    sub(state) {
      state.count = state.count - 1
      return {...state}
    }
  },
  effects: {*addCount(action, { call, put}) {console.log(action, action.payload) // 拿到传入的 payload
      yield put({type: 'add'})
    },
    *subCount(action, { call, put}) {console.log(action, action.payload) // 拿到传入的 payload
      yield put({type: 'sub'})
    }
  },
}

export default model

连贯组件

应用 connect 连贯组件,都挂到 props 中去

import React from 'react'
import {connect} from 'dva'

function DvaDemo({dvamodel, dispatch}) {console.log(dvamodel) // 通过命令空间拜访
  return (
    <div>
      <h2>Dva</h2>
      <p> 点击数:{dvamodel.count}</p>
      <button onClick={() => dispatch({
        type: 'dvamodel/addCount',
        payload: 1
      })}> 点击 +</button>
      <button onClick={() => dispatch({
        type: 'dvamodel/subCount',
        payload: 1
      })}> 点击 -</button>
    </div>
  )
}

export default connect((props) => props)(DvaDemo);

总结

通过简略的应用尝试,感觉还是 Mobx 是最简略

欢送关注【前端学啥】一起交换

退出移动版