前端
PythonJava运维数据库
状态管理
状态管理
  • 🖥️Redux Tookit
    • Introduction
      • 介绍
    • Tutorials
      • 🖥️快速开始
      • 🏐在TypeScript环境使用
    • Using Redux toolkit
      • 使用Immer编写Reducers
      • 性能与数据范式化
      • 异步逻辑与数据请求
      • Usage With TypeScript
    • API Refrence
      • Store Setup
        • configureStore
        • getDefaultMiddleware
        • Immutability Middleware
        • Serializability Middleware
        • Action Creator Middleware
        • createListenerMiddleware
        • createDynamicMiddleware
        • getDefaultEnhancers
        • autoBatchEnhancer
      • Reducer and Actions
        • createReducer
        • createAction
        • createSlice
        • createAsyncThunk
        • createEntityAdapter
        • combineSlices
      • Other
        • createSelector
        • Matching Utilities
    • RTX Query
      • RTK Query Overview
      • Comparson with Other Tools
      • Examples
      • Usage With TypeScript
      • Using RTK Query
        • Queries
        • Mutations
      • API Refrence
        • createApi
        • fetchBaseQuery
        • ApiProvider
        • setupListeners
        • Generated API Slices
          • Generated API Slices
          • Redux Integration
          • Endpoints
          • Code Splitting
          • Utilities
          • React Hooks
  • 🚚Redux-Saga
    • 入门
    • 基础概念
    • API
    • 技巧
  • 🚑React Redux
    • 安装
    • 教程
    • 使用 React Redux
    • API 参考
  • 🚕生态
    • Redux Persist
    • zustand
      • 使用 useShallow 防止重新渲染
由 GitBook 提供支持
在本页
  • 使用 Saga 辅助函数
  • 声明式Effects
  • 发起 action 到 store
  • 错误处理

这有帮助吗?

  1. Redux-Saga

基础概念

使用 Saga 辅助函数

redux-saga提供一些辅助函数,包装了一些内部方法,用来在一些特定的action被发起到store时派生任务。

这些辅助函数构建在低阶API之上,我们将会在高阶概念中看到这些函数是如何实现的。

第一个函数takeEvery,是最常见的,它提供了类似redux-thunk的行为。

让我们通过下面的例子演示一下。每次点击Fetch按钮,我们发起一个FETCH_REQUESTED的action。我们通过从服务器获取一些数据,来处理这个action。

首先我们创建一个异步action任务:

import { call, put } from 'redux-saga/effects'

export function* fetchData(action) {
   try {
      const data = yield call(Api.fetchUser, action.payload.url);
      yield put({type: "FETCH_SUCCEEDED", data});
   } catch (error) {
      yield put({type: "FETCH_FAILED", error});
   }
}

然后在每次 FETCH_REQUESTED action 被发起时启动上面的任务。

import { takeEvery } from 'redux-saga'

function* watchFetchData() {
  yield* takeEvery('FETCH_REQUESTED', fetchData)
}

在上面的例子中,takeEvery 允许多个 fetchData 实例同时启动。在某个特定时刻,尽管之前还有一个或多个 fetchData 尚未结束,我们还是可以启动一个新的 fetchData 任务,

如果我们只想得到最新那个请求的响应(例如,始终显示最新版本的数据)。我们可以使用 takeLatest 辅助函数。

import { takeLatest } from 'redux-saga'

function* watchFetchData() {
  yield* takeLatest('FETCH_REQUESTED', fetchData)
}

和 takeEvery 不同,在任何时刻 takeLatest 只允许一个 fetchData 任务在执行。并且这个任务是最后被启动的那个。 如果已经有一个任务在执行的时候启动另一个 fetchData ,那之前的这个任务会被自动取消。

如果你有多个 Saga 监视不同的 action ,你可以用内置辅助函数创建很多观察者,就像用了 fork 来派生他们 (之后我们会讲到 fork ,现在就把它当作一个允许我们在后台启动多个 saga 的 Effect )。

import { takeEvery } from 'redux-saga/effects'

// FETCH_USERS
function* fetchUsers(action) { ... }

// CREATE_USER
function* createUser(action) { ... }

// 同时使用它们
export default function* rootSaga() {
  yield takeEvery('FETCH_USERS', fetchUsers)
  yield takeEvery('CREATE_USER', createUser)
}

声明式Effects

在redux-saga中,Saga 是通过Generator函数实现的。为了表达Saga的逻辑,我们从Generator中产出纯 JavaScript 对象。我们将这些对象称为Effect。Effect是一个包含有待中间件解释的一些信息的对象。你可以将Effect视为向中间件发出的执行某种操作(例如,调用某个异步函数、向store派发action等)的指令。

在Redux-Saga中,你可以使用redux-saga/effects包中提供的函数来创建Effects,

Saga可以产出多种形式的Effects。最简单的方式是产出一个Promise。

例如,假设我们有一个Saga,它监听PRODUCTS_REQUESTED这个action,每当匹配到action时,它会启动一个从服务器上获取产品列表的任务。

import { takeEvery } from 'redux-saga/effects'
import Api from './path/to/api'

function* watchFetchProducts() {
  yield takeEvery('PRODUCTS_REQUESTED', fetchProducts)
}

function* fetchProducts() {
  const products = yield Api.fetch('/products')
  console.log(products)
}

发起 action 到 store

redux-saga 为此提供了另外一个函数 put,这个函数用于创建 dispatch Effect。

import { call, put } from 'redux-saga/effects'
//...

function* fetchProducts() {
  const products = yield call(Api.fetch, '/products')
  // 创建并 yield 一个 dispatch Effect
  yield put({ type: 'PRODUCTS_RECEIVED', products })
}

错误处理

上一页入门下一页API

最后更新于1年前

这有帮助吗?

🚚