redux-saga 和 redux-toolkit 关于如何正确导航代码的混淆
redux-saga and redux-toolkit confusion on how to navigate code correctly
我是新手,所以这里可能缺少信息。以下传奇已注册
function* onboardingListener() {
yield takeEvery(ENROLL_CRED_STATUS_REQUEST, onboarding);
}
function* onboarding(enrollFormUsername) {
// a few lines of code that are not important 'I think'
yield put(enrollGetContactByUsername(username));
const { contactSuccess } = yield race({
contactSuccess: take(ENROLL_CONTACT_FIND_SUCCESS),
contactFailure: take(ENROLL_CONTACT_FIND_FAILURE),
});
}
export function enrollGetContactByUsername(username) {
const config = {
baseURL: ENV_VARS.BASE_URL_CONTACT,
url: '/contact/enroll',
method: 'GET',
params: {
email: `${username}`,
},
};
return {
type: 'API_CALL',
config,
auth: false,
spinner: true,
successAction: ENROLL_CONTACT_FIND_SUCCESS,
failureAction: ENROLL_CONTACT_FIND_FAILURE,
};
}
我看到 ENROLL_CRED_STATUS_REQUEST 已连接,我猜这是入职调用开始的时间,所以不确定我是否需要提供所有 react-redux 代码。
查看 redux 文档,我看到这样的代码
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
这对我来说很有意义。我不明白我上面的代码是如何调用远程服务器的,以及为什么在上面的代码中调用 call() 或 fork() 。上面的代码究竟是如何工作的? (我觉得我真的很接近连接点,但还没有完全连接起来)
enrollGetContactByUsername
是一个动作创建器,它创建一个类型为 API_CALL
的新动作,然后您可以在 onboarding
saga 中发送该动作。我怀疑您在某处 运行 有另一个 saga 并监听此操作以处理请求。 Saga saga 可能看起来类似于下一个片段,除了它使用提供的配置而不是 Api.authorize
。所以像:
function * apiCallSaga() {
yield takeEvery(API_CALL, function * (action) {
try {
const method = axios[config.method.toLowerCase()]
const fullUrl = config.baseURL + config.url
const {data} = yield call(method, fullUrl, config.params)
yield put({type: config.successAction, data})
} catch (err) {
yield put({type: config.failureAction, err})
}
}
}
回答你的第二个问题。当你想调用一个 returns 承诺的函数时,你可以使用 call
或 fork
。不同之处在于 yielding call
等待结果 - 类似于异步函数中的 await
- 因此您可以将其分配给变量以获得承诺的结果。另一方面,fork
是 non-blocking 效果,而不是 returns 立即成为“任务描述符”,这就像传奇世界中的承诺。然后你可以例如在代码后面使用 join
效果等待结果。在 99% 的情况下,当发出 api 请求时,您希望在发出请求的代码行获得结果,因此您将使用 call
效果。
我是新手,所以这里可能缺少信息。以下传奇已注册
function* onboardingListener() {
yield takeEvery(ENROLL_CRED_STATUS_REQUEST, onboarding);
}
function* onboarding(enrollFormUsername) {
// a few lines of code that are not important 'I think'
yield put(enrollGetContactByUsername(username));
const { contactSuccess } = yield race({
contactSuccess: take(ENROLL_CONTACT_FIND_SUCCESS),
contactFailure: take(ENROLL_CONTACT_FIND_FAILURE),
});
}
export function enrollGetContactByUsername(username) {
const config = {
baseURL: ENV_VARS.BASE_URL_CONTACT,
url: '/contact/enroll',
method: 'GET',
params: {
email: `${username}`,
},
};
return {
type: 'API_CALL',
config,
auth: false,
spinner: true,
successAction: ENROLL_CONTACT_FIND_SUCCESS,
failureAction: ENROLL_CONTACT_FIND_FAILURE,
};
}
我看到 ENROLL_CRED_STATUS_REQUEST 已连接,我猜这是入职调用开始的时间,所以不确定我是否需要提供所有 react-redux 代码。
查看 redux 文档,我看到这样的代码
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
这对我来说很有意义。我不明白我上面的代码是如何调用远程服务器的,以及为什么在上面的代码中调用 call() 或 fork() 。上面的代码究竟是如何工作的? (我觉得我真的很接近连接点,但还没有完全连接起来)
enrollGetContactByUsername
是一个动作创建器,它创建一个类型为 API_CALL
的新动作,然后您可以在 onboarding
saga 中发送该动作。我怀疑您在某处 运行 有另一个 saga 并监听此操作以处理请求。 Saga saga 可能看起来类似于下一个片段,除了它使用提供的配置而不是 Api.authorize
。所以像:
function * apiCallSaga() {
yield takeEvery(API_CALL, function * (action) {
try {
const method = axios[config.method.toLowerCase()]
const fullUrl = config.baseURL + config.url
const {data} = yield call(method, fullUrl, config.params)
yield put({type: config.successAction, data})
} catch (err) {
yield put({type: config.failureAction, err})
}
}
}
回答你的第二个问题。当你想调用一个 returns 承诺的函数时,你可以使用 call
或 fork
。不同之处在于 yielding call
等待结果 - 类似于异步函数中的 await
- 因此您可以将其分配给变量以获得承诺的结果。另一方面,fork
是 non-blocking 效果,而不是 returns 立即成为“任务描述符”,这就像传奇世界中的承诺。然后你可以例如在代码后面使用 join
效果等待结果。在 99% 的情况下,当发出 api 请求时,您希望在发出请求的代码行获得结果,因此您将使用 call
效果。