为了账号安全,请及时绑定邮箱和手机立即绑定

react-redux 中间件中的“下一个”如何工作?

react-redux 中间件中的“下一个”如何工作?

www说 2022-06-16 15:19:43
我是 React 和 Redux 的新手。我有一个简单的应用程序,您可以在其中将输入文本添加到无序列表中。我有防止显示特定单词的中间件。我不明白实现中间件的操作顺序。据我了解,当我触发调度时,会发生以下情况:从表单提交事件触发调度// title is an object with a stringfunction handleSubmit(event) {    props.addArticle(title);}通过中间件功能:// store.jsconst store = createStore(  rootReducer, // this is defined elsewhere and effectively handles actions  applyMiddleware(forbiddenWordsMiddleware));// middleware.jsimport { ADD_ARTICLE } from "../constants/constants.js";const forbiddenWords = ["spam", "money"];export function forbiddenWordsMiddleware({ dispatch }) {    return function (next) {        return function (action) {            if (action.type === ADD_ARTICLE) {                const foundWord = forbiddenWords.filter((word) =>                    action.payload.title.includes(word)                );                if (foundWord.length) {                    return dispatch({ type: "FOUND_BAD_WORD" });                }            }            return next(action);        };    };}上述函数实际上如何与 createStore 和 applyMiddleware 一起工作?让我特别困惑的是这next(action)条线。下一步和行动从何而来?我无法想象从表单提交到检查禁用词的线性执行。
查看完整描述

2 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

store.dispatch中间件围绕实际的 Redux功能形成管道。当您调用 时store.dispatch(action),您实际上是在调用链中的第一个中间件。在中间件内部,next将值传递给下一个中间件,同时storeAPI.dispatch重新启动管道。 action是传入dispatch(或next从前一个中间件传入)的值。

这种可视化可能会有所帮助:

//img1.sycdn.imooc.com//62aad9ab0001cf4b07800164.jpg

诚然,实际的实现是一些神奇的代码,但您不必担心。

有关更多详细信息,请参阅我的“Redux 基础研讨会”幻灯片的“可扩展性和中间件”部分,以及有关 Redux 中间件如何工作的这些文章


查看完整回答
反对 回复 2022-06-16
?
SMILET

TA贡献1796条经验 获得超4个赞

在这种情况下,next仅仅意味着这个中间件对那个特定的动作不感兴趣,并且想把它传递给其他中间件来处理它。


当您将中间件提供给 applyMiddleware 函数时,它首先调用每个中间件并将其传递给middlewareAPI 此处调用的内容。然后从最后一个中间件开始,调用它并给store.dispatch它,然后将它的结果发送给中间件,中间件在最后一个之前。并继续这样(将后一个中间件的结果传递给它之前的中间件)一直到第一个中间件。


所以假设你有这三个中间件:[a, b, c]你把它们都传递给 applyMiddleware 函数。这是发生的事情:


首先,每个中间件都被middlewareAPI对象调用,它基本上是一个包含原始store.dispatch和的对象store.getState。


const middlewareAPI = { getState: store.getState, dispatch: store.dispatch }

const aInChain = a(middlewareAPI);

const bInChain = b(middlewareAPI);

const cInChain = c(middlewareAPI);

其次,我们调用每个中间件,其结果是之前调用中间件的结果。期待最后一个中间件,它后面没有任何东西,并将原始调度作为输入。


const finalC = cInChain(store.dispatch);

const finalB = bInChain(finalC);

const finalA = aInChain(finalB);

然后我们将第一个中间件的最终版本设置为新增强存储的调度。因此,例如,当您调用 时store.dispatch({ type: "Hello" }),该finalA函数被调用,如果它调用finalB作为 提供给它的函数,则next链中的下一个中间件将被调用,无论finalA它给出什么动作。整个链条都是这样的。


因此,在我们在问题中的示例中,中间件中有两个返回语句。第一个是return dispatch({...}),第二个是return next({...})。


在它们两个中,我们的中间件都说它已经完成了这个动作的工作并让调度链继续;但是在第一个 return 语句中,中间件dispatch直接调用原始的,并将一个新类型的新动作传递给dispatch. 所以最初传递给我们中间件的动作将被完全遗忘。该语句在 action 到达 store 之前中断了中间件的链,并使用新的 action 开始新的 dispatch。


在第二次返回中,我们的中间件调用该next函数,正如我之前描述的,它是该行中的下一个中间件,我们的中间件将原始的发送action给它而不做任何更改。所以结果就像这个中间件根本不存在一样。


在这种情况下,我们的中间件只是说“我不关心这个动作是什么;我想把它发送到下一个中间件来决定它是否应该到达store.dispatch”。


查看完整回答
反对 回复 2022-06-16
  • 2 回答
  • 0 关注
  • 189 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号