状态管理之 redux、dva、vuex

前言

日常积累,欢迎指正

1、状态管理之 redux、dva、vuex

1.1、redux

Redux is a predictable state container for JavaScript apps - Redux是一个可预测的 JavaScript 应用程序状态容器

redux 中

  • dispatch(action/actionCreator) 触发 state 修改
  • state 修改引发页面重新渲染

异步处理:借助 redux-saga 等工具实现

container 组件示例


import App from '../pages/App'
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { IStoreState } from '../types/todoList'
import { willToDone, doneToWill,del, add } from '../actions/todoList'

interface IProps {}

const mapStateToProps = (state: IStoreState, ownProps: IProps) => {
    return {
        todoList: state.todoList
    }
}

const mapDispatchToProps = (dispatch: Dispatch, ownProps: IProps) => {
    return {
        willToDone: (id: number ) => {
            dispatch(willToDone(id))
        },
        del: (id: number) => {
            dispatch(del(id))
        },
        doneToWill: (id: number) => {
            dispatch(doneToWill(id))
        },
        add: (text:string) => {
            console.log('dispatch', text)
            dispatch(add(text))
         }
    }
}
const connector = connect(mapStateToProps, mapDispatchToProps)
export default connector(App as any)

redux demo 的分支 20191226-up-async

1.2、dva

dva= react-router + redux-saga
dva 是一个整合 react-router + redux-saga 的轻量级框架,它的前身是支付宝的 React + redux 最佳解决方案。
经过封装之后一定程度的简化了操作。
dva 最核心的是提供了 app.model 方法来使用 model,dva 中的 model 用于把 reducer, initialState, action, saga 封装到一起

import { listStatus,actionType } from '../constants/todoList'
import { asyncAdd } from '../services/todoList'

export const todoList = 'todoList'

export default {
  namespace: todoList,
  /** @desc initialState */
  state: [
    {
      id: 0.186864004695098,
      status: listStatus.WILLDO,
      text: "sbfynhjum1111"
    },
    {
      id: 0.186866666695098,
      status: listStatus.WILLDO,
      text: "vxbgym666"
    },
    {
      id: 0.186865004695778,
      status: listStatus.DONE,
      text: "5555555"
    },
    {
      id: 0.1861115004695778,
      status: listStatus.DONE,
      text: "fffff9999999999"
    }
  ],
  /** @desc reducer */
  reducers: {
    ADD(state, action) {
      // console.log(state,action)
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          status: action.status
        }
      ]
    },
    DONE(state, action) {
      return state.map(item => {
        if (item.id === action.id) {
          item.status = listStatus.DONE
        }
        return item
      })
    },
    WILLDO(state, action) {
      return state.map(item => {
        if (item.id === action.id) {
          item.status = listStatus.WILLDO
        }
        return item
      })
    },
    DEL(state, action) {
      return state.filter(item => item.id !== action.id)
    }
  },
  /** @desc saga */
  effects: {
    /**
     * *(action, effects) => void
     * 或
     * [*(action, effects) => void, { type }]
     */
    *addAsync(action, effects) {
      // console.log(action)
      const result = yield effects.call(asyncAdd, action.text)
      // console.log(result)
      yield effects.put({
        type:`${todoList}/${actionType.ADD}`,
        id: action.id,
        text: result,
        status: action.status
      })
    }
  },
  subscriptions: {

  }
};

dva 的原则是实现上尽量不创建新语法,而是用依赖库本身的语法,所以与原生的 redux 使用起来非常的相似。

dva 中依旧是

  • dispatch(action/actionCreator) 触发 state 修改
  • state 修改引发页面重新渲染

需要注意的点就是 dva 中 action 的 type 均为 namespace/ 开头 - namespace/reducers.attr 或 namespace/effects.attr

异步处理:使用 model 的 effects ,这里的 effects 的底层是 redux-saga

dva demo 的分支 02-demo

1.3、vuex

vuex 中一个 store module 的结构与 dva 中 model 的结构比较相似

const moduleA = {
  namespaced: true, // 开启命名空间
  state: { ... },

  /**
  * 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
  * 注意: mutations 只能是同步地更改状态。
  */
  mutations: { ... },

  /**
  * Action 类似于 mutation,不同在于:
  * Action 提交的是 mutation,而不是直接变更状态。
  * Action 可以包含任意异步操作。
  */
  actions: { ... },
  
  /**
  * 类似 store 的计算属性
  * 就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,
  * 且只有当它的依赖值发生了改变才会被重新计算。
  */
  getters: { ... }
}

对比 redux 需要注意的是:

  • vuex 中也有 dispatch 方法 - $store.dispatch(‘xxx’) ,但 vuex 中的 dispatch 与 redux 的 dispatch 不一样

    • vuex 是分发 action,可以理解为 dispatch 只是将 vuex 中的 action 能够让 vue 组件调用到,它的简单处理是 vuex 的 mapActions 方法,
  • vuex 的 action 与 redux 中的 action 也不一样

    • vuex 的 Action 提交的是 mutation,而不是直接变更状态。
    • vuex 的 Action 可以包含任意异步操作。
  • vuex 中还有 mutation - 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
    vuex 对 state 操作的整个过程为:

  • dispatch 分发 action

  • action 提交 mutation

  • mutation 修改 state

  • state 修改触发页面展示更新





vuex demo 中的 3-vuex

你可能感兴趣的:(dva,vuex,redux,vuex,redux,dva)