使用 Redux-Saga 而不是在 React 组件中编写异步函数有什么好处?
Any benefits to use Redux-Saga instead of writing async func in react components?
反应版本是 16.13.1.
我想知道将 redux-saga 用于异步方法是否有一些好处。
const component = () => {
const asyncFunc = async() => { // <- this part should be moved out to redux-saga?
await callMethod();
}
return (
<div onClick={asyncFunc}>button</div>
)
}
我不知道 asyncFunc
应该在 redux-saga 或 react 组件中调用。
哪个更好或更有益?
在我看来,我更喜欢在组件中调用异步方法。
使用几乎所有 redux 的好处是组织代码并保存所有状态,如果你在一个组件中使用异步函数并且碰巧你想为其他组件再次使用该异步函数组件然后你必须一次又一次地编写整个代码,在 redux-saga 的情况下你将编写一次异步并且可以在整个反应项目中的任何地方调用该操作,现在你可能正在创建 5-10 个组件但它可能将来您可能会创建 5000 个组件,届时 redux 及其中间件将发挥作用。
简单来说,redux-saga
在我们需要在 redux 操作期间实现一些异步操作的情况下是有益的。
现在您正在做的是处理组件中的副作用,因此您要分派的操作只会更新商店。
这是一个非常简单的用例,您在组件中处理了它,请考虑这样一个场景,您需要来自 2 个不同组件的相同功能。您将不得不在 2 个不同组件中复制逻辑。
测试会变得困难。
现在再次考虑相同的场景,但问题是因为您可以从 2 个组件触发 API 调用,让我们考虑用户同时从两个组件触发 API 调用的场景,如果第一个 API 调用仍未决,则处理两个 API 调用是资源浪费。
对于所有这种情况,redux-saga 提供了 takeLatest
、takeEvery
等方法
Redux-saga 是一个中间件,可以在动作到达 reducer 之前对其进行处理。
基本上,所有副作用都将在中间件中处理,让您更好地控制效果。
这样一来,关注点分离 中间件将处理副作用而不是组件。 saga 不依赖于组件的生命周期。
在 saga 中,fetch 看起来像这样:
function* fetchItems(action) {
try {
const result = yield call(axios.post, ...);
yield put ({ type: 'FETCH_SUCCESS', payload: { result } });
} catch (e) {
yield put ({ type: 'FETCH_FAILED', error: { msg: e } });
}
}
yield takeEvery(FETCH_ITEMS, fetchItems);
但是对于具有后台处理的复杂系统,您可以实现使用 fork()
和 cancel()
的不同模式
function* doSync() {}
function* main() {
while ( yield take(START_SYNC) ) {
const task = yield fork(doSync) // returns a task
yield take(STOP_SYNC)
yield cancel(task) // cancel a task if syncing is stopped
}
}
因此,综上所述,当您的系统变得更加复杂和事件驱动时,redux-saga 的力量就体现出来了。
反应版本是 16.13.1.
我想知道将 redux-saga 用于异步方法是否有一些好处。
const component = () => {
const asyncFunc = async() => { // <- this part should be moved out to redux-saga?
await callMethod();
}
return (
<div onClick={asyncFunc}>button</div>
)
}
我不知道 asyncFunc
应该在 redux-saga 或 react 组件中调用。
哪个更好或更有益?
在我看来,我更喜欢在组件中调用异步方法。
使用几乎所有 redux 的好处是组织代码并保存所有状态,如果你在一个组件中使用异步函数并且碰巧你想为其他组件再次使用该异步函数组件然后你必须一次又一次地编写整个代码,在 redux-saga 的情况下你将编写一次异步并且可以在整个反应项目中的任何地方调用该操作,现在你可能正在创建 5-10 个组件但它可能将来您可能会创建 5000 个组件,届时 redux 及其中间件将发挥作用。
简单来说,redux-saga
在我们需要在 redux 操作期间实现一些异步操作的情况下是有益的。
现在您正在做的是处理组件中的副作用,因此您要分派的操作只会更新商店。
这是一个非常简单的用例,您在组件中处理了它,请考虑这样一个场景,您需要来自 2 个不同组件的相同功能。您将不得不在 2 个不同组件中复制逻辑。
测试会变得困难。
现在再次考虑相同的场景,但问题是因为您可以从 2 个组件触发 API 调用,让我们考虑用户同时从两个组件触发 API 调用的场景,如果第一个 API 调用仍未决,则处理两个 API 调用是资源浪费。
对于所有这种情况,redux-saga 提供了 takeLatest
、takeEvery
等方法
Redux-saga 是一个中间件,可以在动作到达 reducer 之前对其进行处理。
基本上,所有副作用都将在中间件中处理,让您更好地控制效果。
这样一来,关注点分离 中间件将处理副作用而不是组件。 saga 不依赖于组件的生命周期。
在 saga 中,fetch 看起来像这样:
function* fetchItems(action) {
try {
const result = yield call(axios.post, ...);
yield put ({ type: 'FETCH_SUCCESS', payload: { result } });
} catch (e) {
yield put ({ type: 'FETCH_FAILED', error: { msg: e } });
}
}
yield takeEvery(FETCH_ITEMS, fetchItems);
但是对于具有后台处理的复杂系统,您可以实现使用 fork()
和 cancel()
function* doSync() {}
function* main() {
while ( yield take(START_SYNC) ) {
const task = yield fork(doSync) // returns a task
yield take(STOP_SYNC)
yield cancel(task) // cancel a task if syncing is stopped
}
}
因此,综上所述,当您的系统变得更加复杂和事件驱动时,redux-saga 的力量就体现出来了。