Redux
整个应用只有一个Store:单一数据源
Store.state不能直接修改(只读),必须调用dispatch(action) => store.reducer => return newState
Action是一个对象,且必须具有type属性,用来告诉reducer执行哪个操作
reducer必须是一个纯函数,以此来保证相同的输入必定是相同的输出,确保返回的newState可预测可控
大型应用中可以有多个reducer,通过combineReducer 来整合成一个根reducer
-
Redux的大概流程:
// view中发出 Action store.dispatch(action) // store 自动调用reducer,传入当前state和action let newState = xxxReducer(currentState, action) // state发生变化,store自动调用监听函数 store.subsrcibe(listener) // listener可以通过 store.getState() 得到当前状态。如果使用的是 React,这时可以触发重新渲染 View function listerner() { let newState = store.getState(); component.setState(newState); }
Vuex
- 由 State + Muatations(commit) + Actions(dispatch) 组成
- 全局只有一个Store实例(单一数据源)
- Mutations必须是同步事务,Why?:不同步修改的话,会很难调试,不知道改变什么时候发生,也很难确定先后顺序,A、B两个 mutation,调用顺序可能是 A -> B,但是最终改变 State 的结果可能是 B -> A
- Actions 负责处理异步事务,然后在异步回调中触发一个或多个mutations,当然,也可以在业务代码中处理异步事务,然后在回调中同样操作
- 模块化通过module方式来处理,这个跟Redux-combineReducer类似,在应用中可以通过namespaceHelper来简化使用
对比Redux
Redux:
// view——>actions——>reducer——>state变化——>view变化(同步异步一样)
Vuex:
// view——>commit——>mutations——>state变化——>view变化(同步操作)
// view——>dispatch——>actions——>mutations——>state变化——>view变化(异步操作)
总的来说都是让 View 通过某种方式触发 Store 的事件(mutation)或方法(reducer),Store 的事件或方法对 State 进行修改(state.xxx = xxx)或返回一个新的 State(return newState),State 改变之后,View 发生响应式改变(setState vs 数据劫持响应式)。