【问题标题】:Dispatch action from saga in order to reach reducer while that action is being watched by the same saga在同一个 saga 监视该动作时,从 saga 调度动作以到达减速器
【发布时间】:2021-08-07 02:14:32
【问题描述】:

当我从我的组件运行getUser() 以调度GET_USER 类型的动作时,该动作被我的传奇捕获。然后通过使用getUserInfo(),我发出请求以获取一些数据并为了更新状态,我分派了一个 GET_USER_SUCCESS 并将结果作为有效负载。这是一个不好的方法吗?

我能否以某种方式再次从 saga 中调度 GET_USER,将结果作为有效负载传递,而不让 saga 拦截它以便它可以到达减速器?

actionTypes.js

export const GET_USER = "GET_USER"
export const GET_USER_SUCCESS = "GET_USER_SUCCESS"
export const GET_USER_FAIL = "GET_USER_FAIL"

actions.js

import {
    GET_USER,
    GET_USER_SUCCESS,
    GET_USER_FAIL
} from "./actionTypes"

export const getUser = () => ({
    type: GET_USER,
})

export const getUserSuccess = data => ({
    type: GET_USER_SUCCESS,
    payload: data,
})

export const getUserFail = error => ({
    type: GET_USER_FAIL,
    payload: error,
})

saga.js

import { call, put, takeEvery } from "redux-saga/effects"
import { GET_USER } from "./actionTypes"
import { getUser, getUserSuccess, getUserFail } from "./actions"

import { getUserInfo } from "../../../helpers/backend_helper"

function* getUserInformation() {
    try {
        const user_response = yield call(getUserInfo)
        if (user_response && user_response.id)
            yield put(getUserSuccess(user_response))
        else
            yield put(getUserFail('could not fetch user'))
    } 
    catch (error) {
        yield put(apiError("Bad response from server"))
    }
}

function* userSaga() {
    yield takeEvery(GET_USER, getUserInformation)
}

export default userSaga

backend_helper.js

import { post, del, get, put } from "./api_helper"
const getUserInfo = () => get("/users/me/")

【问题讨论】:

  • 我真的不确定您所说的“我可以以某种方式从 saga 中再次调度 GET_USER 并将结果作为有效负载传递,而无需 saga 拦截它以便它可以到达减速器”。您的代码看起来很合理。
  • 很高兴听到...我的意思是代替 getUserSuccess(user_response) 使用 getUser(user_response) 而不会导致无限循环
  • 由于您使用的是takeEvery,不,没有办法在不触发无限循环的情况下从您的传奇中调度GET_USER 操作。 IMO 您通过单独的副作用触发操作 (GET_USER) 和响应操作 (GET_USER_SUCCESS) 来遵循 Redux 最佳实践。如果你想拦截一​​个动作,转换它,然后传递它而不触发无限循环,你可以使用标准的Redux middleware并调用next({ ...action, data })

标签: reactjs react-redux redux-saga


【解决方案1】:

我认为您的建议也使调试变得更加困难。你会想要独特的动作; GET_USER 告诉您您正在获取数据,GET_USER_SUCCESS 告诉您您已成功收到信息。

在复杂的 Web 应用程序中,您最多可以看到 20、30 甚至 40 个操作,因此我认为能够区分它们至关重要。

【讨论】:

    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 2021-01-13
    • 2020-01-14
    • 2016-10-12
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多