为什么 redux-saga 比普通的 redux/useReducer 更能解决副作用?
Why does redux-saga solve side effects better than normal redux/ useReducer?
我想知道为什么 Redux-Saga / Redux-Thunk 比普通的 Redux/ useReducer 更好地解决了副作用(即使我不知道真正的副作用是什么以及它如何影响 ReactJS)。
有一个正常的例子来处理调用 api(至于调用 api 意味着产生副作用)
使用普通的 redux/useReducer:
const fetchData = async (offset?: number) => {
dataDispatch({ type: Data.REQUEST });
try {
const result: ResponseBase<undefined, DataModel> = await apiGetData(offset || 0);
if (result.responseCode.toString().startsWith('2')) {
dataDispatch({
type: Data.SUCCESS, payload: {
datas: result.dataArray || [],
pageable: result.pageable
}
})
}
}
catch (err) {
dataDispatch({
type: Data.FAILTURE,
payload: new Error(err.message || '')
});
}
};
useEffect(() => {
fetchData()
}, [])
使用 Redux-Saga:
function* fetchData(offset: number) {
try {
const result: ResponseBase<undefined, DataModel> = yield call(apiGetData, offset);
yield put(DataSuccessAction(result.dataArray, result.pageable));
} catch (e) {
yield put(DataFailureAction(e))
}
}
#code in component
useEffect(() => {
DataRequestAction(10) // 10 is an offset
}, [])
我认为两种实现的结果是一样的。但实施第一个更清晰、更容易。
在这种情况下,Redux-Saga 有什么好处?有人向我详细解释吗?提前致谢。
首先必须要说的是,比较redux-saga
库和useReducer
钩子是不正确的。这些是针对不同情况的不同工具。
useReducer
是一个钩子,它允许您为组件实现类似于 redux 的状态,而无需 redux 或具有复杂的本地状态管理而无需连接到您的 redux 状态(讨论用例不在您的原始问题中) ). 它自己工作。您不需要 redux
即可使用 useReducer
.
redux-saga
只是一个工具,它为您提供了一种使用异步 code/complex 操作处理程序的方法。 它在 redux
之上工作。所以它扩展了 redux 功能.
这是一个如何将它与 useReducer
一起使用的示例。 Github issue link。
虽然没有检查它是否有效,但仍然有效。
我认为两种实现的结果是一样的。 但是实施第一个更清晰、更容易。在这种情况下 Redux-Saga 有什么好处?有人向我详细解释吗?提前致谢。
你已经自己回答了你的问题。
但是有可能使第一个示例更清晰且更易于阅读。例如,您可以添加动作创建者而不是在 fetchData
函数内生成对象。在 saga
的示例中,没有 if
语句使 useReducer
的示例变得丑陋。
最终,代码的效率取决于您编写代码的方式(在大多数情况下),而不取决于您使用的库。任何库或工具都可以完成可怕的事情。
我想知道为什么 Redux-Saga / Redux-Thunk 比普通的 Redux/ useReducer 更好地解决了副作用(即使我不知道真正的副作用是什么以及它如何影响 ReactJS)。
有一个正常的例子来处理调用 api(至于调用 api 意味着产生副作用)
使用普通的 redux/useReducer:
const fetchData = async (offset?: number) => {
dataDispatch({ type: Data.REQUEST });
try {
const result: ResponseBase<undefined, DataModel> = await apiGetData(offset || 0);
if (result.responseCode.toString().startsWith('2')) {
dataDispatch({
type: Data.SUCCESS, payload: {
datas: result.dataArray || [],
pageable: result.pageable
}
})
}
}
catch (err) {
dataDispatch({
type: Data.FAILTURE,
payload: new Error(err.message || '')
});
}
};
useEffect(() => {
fetchData()
}, [])
使用 Redux-Saga:
function* fetchData(offset: number) {
try {
const result: ResponseBase<undefined, DataModel> = yield call(apiGetData, offset);
yield put(DataSuccessAction(result.dataArray, result.pageable));
} catch (e) {
yield put(DataFailureAction(e))
}
}
#code in component
useEffect(() => {
DataRequestAction(10) // 10 is an offset
}, [])
我认为两种实现的结果是一样的。但实施第一个更清晰、更容易。 在这种情况下,Redux-Saga 有什么好处?有人向我详细解释吗?提前致谢。
首先必须要说的是,比较redux-saga
库和useReducer
钩子是不正确的。这些是针对不同情况的不同工具。
useReducer
是一个钩子,它允许您为组件实现类似于 redux 的状态,而无需 redux 或具有复杂的本地状态管理而无需连接到您的 redux 状态(讨论用例不在您的原始问题中) ). 它自己工作。您不需要 redux
即可使用 useReducer
.
redux-saga
只是一个工具,它为您提供了一种使用异步 code/complex 操作处理程序的方法。 它在 redux
之上工作。所以它扩展了 redux 功能.
这是一个如何将它与 useReducer
一起使用的示例。 Github issue link。
虽然没有检查它是否有效,但仍然有效。
我认为两种实现的结果是一样的。 但是实施第一个更清晰、更容易。在这种情况下 Redux-Saga 有什么好处?有人向我详细解释吗?提前致谢。
你已经自己回答了你的问题。
但是有可能使第一个示例更清晰且更易于阅读。例如,您可以添加动作创建者而不是在 fetchData
函数内生成对象。在 saga
的示例中,没有 if
语句使 useReducer
的示例变得丑陋。
最终,代码的效率取决于您编写代码的方式(在大多数情况下),而不取决于您使用的库。任何库或工具都可以完成可怕的事情。