【发布时间】: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