React和Vue语法并排比较:状态管理

2020-10-17 15:48:22 蜻蜓队长

这是有关React和Vue语法比较的第二篇文章。在本文中,将比较两种生态系统中最著名的状态管理库(Redux和Vuex)的语法。

React.js和Vue.js的语法并列比较

议程

  • 创建Store
  • Action
  • 异步Action
  • Reducer | Mutation
  • Combine-Reducers | Modules
  • Connect-with-Component
  • 中间件 | 插件
  • Selector | Getter
  • DevTools

创建Store

Redux: redux.js.org/basics/stor…

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
const store = createStore(todoApp)
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
复制代码

Vuex: vuex.vuejs.org/guide/

const store = new Vuex.Store({
  state: { ... },
  mutations: { ... }
})
...
new Vue({
  el: '#app',
  store,
});
复制代码

Action

Redux: redux.js.org/basics/acti…

const ADD_TODO = 'ADD_TODO'
function addTodo(text) {
  return {
    type: ADD_TODO,
    text,
  }
}
复制代码

Vuex: vuex.vuejs.org/guide/actio…

const store = new Vuex.Store({
  actions: {
    increment (context) {
      context.commit('increment') // commit a mutation to trigger state update
    }
  }
})
复制代码

异步Action

Redux(redux-thunk): redux.js.org/advanced/as…

// apply redux-thunk
import thunkMiddleware from 'redux-thunk'
const store = createStore(
  rootReducer,
  applyMiddleware(thunkMiddleware)
)
...
export function fetchPosts() {
  return function (dispatch) {
    dispatch(requestPosts())
    return fetch('xxx')
      .then(response => response.json())
      .then(json => dispatch(receivePosts(json)))
  }
}
复制代码

Vuex: vuex.vuejs.org/guide/actio…

actions: {
  async fetchPosts ({ commit }) {
    commit('requestPosts');
    const res = await fetch('xxx');
    commit('receivePosts', res);
  },
}
复制代码

Reducer | Mutation

Redux(reducer): redux.js.org/basics/redu…

const initialState = {
  todos: [],
}
function todoApp(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false,
          }
        ],
      }
    default:
      return state
  }
}
复制代码

Vuex(mutation): vuex.vuejs.org/guide/mutat…

const store = new Vuex.Store({
  mutations: {
    addTodo (state, payload) {
      state.todos = [
        ...state.todos,
        { text: payload.text, completed: false }
      ]
    }
  }
})
复制代码

Combine-Reducers | Modules

Redux(combine-reducers): redux.js.org/api/combine…

import { combineReducers } from 'redux'
const reducers = combineReducers({
  reducerA,
  reducerB,
})
export default reducers
复制代码

Vuex(modules): vuex.vuejs.org/guide/modul…

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
复制代码

Connect-with-Component

Redux: redux.js.org/basics/usag…

import { connect } from 'react-redux'
import { addTodo } from '../actions'
import TargetComp from '../components/TargetComp'
// state
const mapStateToProps = (state, ownProps) => {
  return {
    todos: state.todos,
  }
}
// action
const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    addTodo: (text) => {
      dispatch(addTodo(text))
    }
  }
}
const TargetContainer = connect(mapStateToProps, mapDispatchToProps)(TargetComp)
export default TargetContainer
复制代码

Vuex

state: vuex.vuejs.org/guide/state…

import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['count']),
  }
}
复制代码

action: vuex.vuejs.org/guide/actio…

import { mapActions } from 'vuex'
export default {
  methods: {
    ...mapActions(['increment']),
  }
}
复制代码

中间件 | 插件

Redux(middleware): redux.js.org/advanced/mi…

import { createStore, combineReducers, applyMiddleware } from 'redux'
const logger = store => next => action => {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  return result
}
const todoApp = combineReducers(reducers)
const store = createStore(
  todoApp,
  applyMiddleware(logger)
)
复制代码

Vuex(plugin): vuex.vuejs.org/guide/plugi…

const myPluginWithSnapshot = store => {
  let prevState = _.cloneDeep(store.state)
  store.subscribe((mutation, state) => {
    let nextState = _.cloneDeep(state)
    // compare `prevState` and `nextState`...
    // save state for next mutation
    prevState = nextState
  })
}
const store = new Vuex.Store({
  ...,
  plugins: process.env.NODE_ENV !== 'production' ? [myPluginWithSnapshot] : [],
})
复制代码

Selector | Getter

Redux(reselect): redux.js.org/recipes/com…

import { createSelector } from 'reselect'
const getTodos = state => state.todos
export const getDoneTodos = createSelector(
  [getTodos],
  todos.filter(t => t.completed),
)
...
import { connect } from 'react-redux'
import TodoList from '../components/TodoList'
import { getDoneTodos } from '../selectors'
const mapStateToProps = state => {
  return {
    doneTodos: getDoneTodos(state)
  }
}
const DoneTodoList = connect(mapStateToProps)(TodoList)
export default DoneTodoList
复制代码

Vuex: vuex.vuejs.org/guide/gette…

const store = new Vuex.Store({
  state: { ... },
  getters: {
    doneTodos: state => {
      return state.todos.filter(t => t.completed)
    }
  }
})
...
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['doneTodos'])
  }
}
复制代码

DevTools

Redux chrome.google.com/webstore/de…

Vuex chrome.google.com/webstore/de…


来源:medium.com/js-dojo,作者:Oahehc (Andrew),翻译:公众号《前端全栈开发者》

以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: 老司机 iOS 周报 #119 | 2020-07.13

下一篇: 「新特性」Spring Boot 全局懒加载机制了解一下

客服紫薇:15852074331
在线咨询
客户经理