在Redux中怎么发起网络请求?
- 创建reducer和action
js
// reducer.js
const initialState = {
loading: false,
data: []
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'DATA_LOADING':
return {
...state,
loading: true
}
case 'DATA_LOADED':
return {
loading: false,
data: action.data
}
}
}
// actions.js
export const loadData = () => {
return dispatch => {
dispatch({ type: 'DATA_LOADING' })
axios.get('http://example.com/data')
.then(res => {
dispatch({ type: 'DATA_LOADED', data: res.data })
})
}
}
redux-saga和redux-thunk有什么本质的区别?
redux-thunk 和 redux-saga 都是 Redux 的中间件,用于处理异步操作。但它们的工作原理不同:
redux-thunk:
- 允许你直接在 action creator 中执行异步逻辑(通常是发起异步请求)。
- action creator 可以返回一个函数,这个函数会被 Redux 自动执行,函数内可以执行异步操作。
- 所以其本质是将异步操作和创建 action 包装在一起,然后由 Redux 执行。
redux-saga:- 使用 Generator 函数来处理异步操作。
- 不直接在 action creator 中执行异步操作,而是通过 Generator 来控制异步流程,获取异步操作的响应结果后再 dispatch action。
- 监听 Redux 的发起的 actions,当检测到某个 action 时会自动执行 Generator 函数。
- 所以其本质是使用 Generator 来控制异步的流程,并在适当的时候再发起 Redux action。
两者的区别在于:
redux-thunk 直接在 action creator 中包装异步逻辑,简单易用,但是 action creator 容易变得很臃肿。
redux-saga 使用 Generator 这种更高级的抽象,代码结构更清晰,但是学习成本较高,难度也较大。
所以如果异步逻辑比较简单,我会推荐使用 redux-thunk。如果异步操作比较复杂,redux-saga 会更有优势,它可以更好地控制异步流程,避免发生 race condition 的问题。
另外,redux-saga 还有其他优势:
- 可以监听 Redux 的所有 dispatch 过的 actions,甚至可以修改 action
- 支持像 takeEvery、takeLatest 这样的高级 api 来控制异步流程。
- 支持 easily testable,使用 redux-saga-test-plan 可以轻易测试 saga
- 可以把所有的异步操作集中在一个文件(saga.js)里面,便于维护。
所以总体来说,我的建议是:
如果是中小型 Redux 应用,使用 redux-thunk 就足够了。
如果是大型复杂应用,为了更好地控制异步流程和维护方便,建议使用 redux-saga。
两者也可以结合使用,比如使用 redux-thunk 处理简单异步操作,redux-saga 处理复杂异步流程。
Redux的实现流程?
- Store初始化:使用createStore()方法创建Redux store。通常会传入rootReducer和初始state。
const store = createStore(rootReducer, initialState);
- State的变化:通过调用store.dispatch(action)方法发送action来变更state。
store.dispatch({ type: 'INCREMENT' });
- State更新: Redux store会调用rootReducer函数来更新state。rootReducer会根据action.type来决定如何更新state。
const rootReducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
};
- 订阅state的变化:通过store.subscribe()方法订阅state的变化,一旦state变化,就会执行回调函数。
store.subscribe(() => console.log(store.getState()));
以上就是Redux工作的4个基本步骤:
- 创建store
- dispatch action
- reducer更新state
- 订阅state变化
具体的工作流程如下: - 调用createStore()创建Redux store,传入rootReducer和初始state。
- 调用store.dispatch(action)发送action。
- store自动调用rootReducer,传入当前state和action,更新state。
- 订阅函数自动执行,可以获取最新的state。
- 如果有其他subscriber,也会依次执行。
- 重复2-5步骤,在React组件中可以监听subscribe()返回的unsubscribe函数来取消订阅。
所以Redux的工作流程就是:
- Action发起
- Reducer计算新状态
- State发生变化
- 订阅函数执行
Mobx的设计思想是什么?
Mobx的设计思想可以归纳为以下3个主要点:
1.基于观察者模式:Mobx 通过 observable 装饰器将数据标记为可观察的,然后任何使用@observer decorator 标记的组件都会在这些数据变化时自动重新渲染。
所以在Mobx中,数据是可观察的,组件是观察者。这来自经典的观察者模式。
2.最小化变化: Mobx 会通过跟踪数据的依赖关系,计算出组件树中受某次修改影响的最小子集,并只重新渲染那些组件。
这种精确控制的重新渲染可以显著提高性能,避免不必要的渲染。
3.简单并可预测: Mobx 通过提供简单的API,让状态与UI之间的关系更加直接和可预测。
比如:
- 通过@observable 装饰器将数据标记为可观察的
- 通过@computed 装饰器将计算属性转化为可观察的
- 通过@observer 装饰器将React组件转化为观察者
- 通过action来修改状态
这些简单而直接的API,让UI=f(state)变得非常清晰和直接。修改状态之后,UI automatical改变,这点很"magical"而且可预测。
所以总结一下,Mobx的三大设计理念是:
1. 基于经典的观察者模式。数据是被观察的,组件是观察者。
2. 精确控制重新渲染,尽可能减少不必要的渲染,提高性能。
3. 简单而直接的API,让状态管理和UI之间的关系更加清晰可预测。
理解了这三点,就掌握了Mobx的基本思想。Mobx通过观察者模式和精确的重新渲染控制,使得状态与UI之间的关系几乎是"magical"的,简单而直接。
这也是Mobx最大的设计理念,简化状态与UI之间的映射关系,让组件动态更新"自动化"。
总而言之,Mobx可以用一句话来概括:
Make state mutations predictable by synchronizing the data state transparently with the UI.
让状态的变化通过同步UI变得可预测和自动化。
这也就是Mobx的宗旨和精髓。