Redux Thunk vs Redux 自定义中间件
Posted
技术标签:
【中文标题】Redux Thunk vs Redux 自定义中间件【英文标题】:Redux Thunk vs Redux custom Middleware 【发布时间】:2020-09-21 20:58:06 【问题描述】:我是 redux 的新手。所以在阅读了很多教程之后。我明白了,redux 需要 redux thunk 通过返回另一个函数来调度异步操作。但是如果我在自定义中间件中调用 http 请求那么
-
是否需要 redux thunk ?
Redux 自定义中间件没有副作用吗?我的意思是不需要返回另一个函数。
如果我使用 redux thunk,那么我的动作创建器看起来像这样。这个我明白了
function incrementAsync()
return (dispatch) =>
setTimeout(() =>
// Yay! Can invoke sync or async actions with `dispatch`
dispatch(increment());
, 1000);
;
我对自定义中间件感到困惑。
https://blog.logrocket.com/managing-asynchronous-actions-in-redux-1bc7d28a00c6/
根据这个博客
const httpMiddleware = store => next => action =>
if (action[HTTP_ACTION])
const actionInfo = action[HTTP_ACTION];
const fetchOptions =
method: actionInfo.verb,
headers: actionInfo.headers,
body: actionInfo.payload || null
;
next(
type: actionInfo.type + "_REQUESTED"
);
fetch(actionInfo.endpoint, fetchOptions)
.then(response => response.json())
.then(data => next(
type: actionInfo.type + "_RECEIVED",
payload: data
))
.catch(error => next(
type: actionInfo.type + "_FAILED",
payload: error
));
else
return next(action);
他们没有在动作中返回任何调度函数。我知道 store,next,action 是内部函数。
谁能帮我理解这件事? 谢谢。
【问题讨论】:
【参考方案1】:All redux-thunk
是一个简单的 redux 中间件,用于检查您的操作是否为函数并相应地执行。您可以在 5 分钟内自行构建。
您可以看到它从 store 对象中解构 dispatch
和 getState
,然后将它们作为参数调用您的操作。
看看它是source code。
因此,您的示例代码可能如下所示:
const httpMiddleware = store => next => action =>
if (action[HTTP_ACTION])
const actionInfo = action[HTTP_ACTION];
const fetchOptions =
method: actionInfo.verb,
headers: actionInfo.headers,
body: actionInfo.payload || null
;
store.dispatch(
type: actionInfo.type + "_REQUESTED"
);
fetch(actionInfo.endpoint, fetchOptions)
.then(response => response.json())
.then(data => store.dispatch(
type: actionInfo.type + "_RECEIVED",
payload: data
))
.catch(error => store.dispatch(
type: actionInfo.type + "_FAILED",
payload: error
));
else
return next(action);
【讨论】:
@Sagi。感谢您的回答。即使我看到了源代码..如果我调用 axios 或在自定义中间件中获取,我可以直接调度操作本身而不是 next(actonType) 另外,如果我使用自定义中间件,则不需要使用 redux thunk。我正确吗? 是的,你是对的。看看我在答案中编辑的示例代码。 @sagi。感谢您的澄清。很明显,自定义中间件不需要 redux thunk。非常感谢【参考方案2】:正如你按点列表询问的那样,我将按点列表回复:
如果我在自定义中间件中调用 http 请求,那么它是必需的吗 redux thunk ?Redux thunk 本身就是一个中间件,如果您想要调度一个执行(例如)AJAX 调用的操作并根据该 AJAX 调用的结果调度两个不同的操作(如果它失败了一个),建议您使用它如果成功则返回一个。
Redux 自定义中间件没有副作用吗?我的意思是不需要返回另一个函数。如果我的理解正确:中间件会简单地接受您调度的操作并将其传递给链,它会让您在将操作发送到减速器“阶段”之前做一些事情。它会做什么完全取决于你。如果需要,您至少需要根据某些逻辑执行下一步(操作)或阻止操作。
最后,像您发布的那个自定义中间件正在根据 AJAX 调用的响应修改您传递的操作,使其更像是一个“拦截器”而不是一个简单的中间件。这么写,不是派发新的动作,更多的是与修改你传递的动作有关。
如果您想根据 ajax 调用的结果调度一个新操作,但不创建中间件/拦截器,您可以这样做:
const postSomethingAction = postObject =>
return async dispatch =>
dispatch(postSomethingPending())
const response = await Api.postSomething(postObject)
if (response.message)
dispatch(postSomethingError(response))
else
dispatch(postSomethingSuccess(response.data))
在这个例子中,我们使用 Thunk 创建一个动作,根据 Api.postSomething 的结果调度另一个动作
【讨论】:
@iba.Great.感谢您发布更多见解 在您的示例中,我想调用 postSomethingAction,然后我需要正确调用它。;就像 dspatch(postSomethingAction (myobject)) 是的,您将发送 postSomething,它最初会产生一个 POST_SOMETHING_PENDING 操作,然后根据 ajax 调用的结果,它会发送一个 POST_SOMETHING_SUCCESS 或 POST_SOMETHING_FAIL,从而更清楚地跟踪状态变化并使您能够做某事,直到服务器响应您的请求。它也比在中间件中做的“魔法”少一点,但它更冗长,因为你需要为所有基于你的 ajax 行为不同的动作编写类似的东西(只有当他们这样做时)以上是关于Redux Thunk vs Redux 自定义中间件的主要内容,如果未能解决你的问题,请参考以下文章
redux-thunk:错误:动作必须是普通对象。使用自定义中间件进行异步操作
Redux Thunk + Axios “操作必须是普通对象。使用自定义中间件进行异步操作。”
Redux thunk - 错误 · 动作必须是普通对象。使用自定义中间件进行异步操作,即使调度具有键类型的对象