Redux-Saga
一个直观的 Redux 副作用管理器。
易于管理,易于测试,并且执行效率高。
异步
ES6 生成器使异步流程易于阅读,编写和测试。创建复杂的副作用,而不会陷入细节。
以组合为中心
Sagas 允许多种方法来解决并行执行,任务并发,任务竞争,任务取消等问题。完全控制代码的流程。
易于测试
在生成器的每个步骤或整个 saga 中断言结果。无论哪种方式,副作用测试都应该快速,简洁且轻松。
示例用法
- 1. 派发一个动作
- 2. 启动一个副作用
- 3. 连接到商店
- 4. 连接到商店(新版本)
假设我们有一个 UI,当点击按钮时,它会从远程服务器获取一些用户数据。(为了简洁,我们只展示触发操作的代码。)
class UserComponent extends React.Component {...onSomeButtonClicked() {const { userId, dispatch } = this.propsdispatch({type: 'USER_FETCH_REQUESTED', payload: {userId}})}...}
该组件向商店分发一个普通对象操作。我们将创建一个 Saga,它会监听所有 USER_FETCH_REQUESTED
操作并触发 API 调用以获取用户数据。
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'import Api from '...'// Worker saga will be fired on USER_FETCH_REQUESTED actionsfunction* fetchUser(action) {try {const user = yield call(Api.fetchUser, action.payload.userId);yield put({type: "USER_FETCH_SUCCEEDED", user: user});} catch (e) {yield put({type: "USER_FETCH_FAILED", message: e.message});}}// Starts fetchUser on each dispatched USER_FETCH_REQUESTED action// Allows concurrent fetches of userfunction* mySaga() {yield takeEvery("USER_FETCH_REQUESTED", fetchUser);}
为了运行我们的 Saga,我们必须使用 redux-saga
中间件将其连接到 Redux 商店。
import { createStore, applyMiddleware } from 'redux'import createSagaMiddleware from 'redux-saga'import reducer from './reducers'import mySaga from './sagas'// Create the saga middlewareconst sagaMiddleware = createSagaMiddleware()// Mount it on the Storeconst store = createStore(reducer,applyMiddleware(sagaMiddleware))// Then run the sagasagaMiddleware.run(mySaga)// Render the application
这是使用 reduxjs/toolkit
中的 configureStore
而不是 Redux
中的 createStore
来运行 saga 的新版本。
import { configureStore } from '@reduxjs/toolkit'import createSagaMiddleware from 'redux-saga'import reducer from './reducers'import mySaga from './sagas'// Create the saga middlewareconst sagaMiddleware = createSagaMiddleware()const middleware = [sagaMiddleware]// Mount it on the Storeconst store = configureStore({reducer,middleware: (getDefaultMiddleware) =>getDefaultMiddleware().concat(middleware),})// Then run the sagasagaMiddleware.run(mySaga)// Render the application