繁体   English   中英

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

[英]How does “next” work in react-redux middleware?

我是 React 和 Redux 的新手。 我有一个简单的应用程序,您可以在其中将输入文本添加到无序列表中。 我有防止显示特定单词的中间件。 我不明白实现中间件的操作顺序。 据我了解,当我触发调度时,会发生以下情况:

  1. 从表单提交事件触发调度
// title is an object with a string
function handleSubmit(event) {
    props.addArticle(title);
}
  1. Go 通过中间件 function:
// store.js
const store = createStore(
  rootReducer, // this is defined elsewhere and effectively handles actions
  applyMiddleware(forbiddenWordsMiddleware)
);
// middleware.js
import { 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);
        };
    };
}

上面的 function 是如何与 createStore 和 applyMiddleware 一起工作的? 让我特别困惑的是next(action)行。 下一步和行动从何而来? 我无法想象从表单提交到检查禁用词的线性执行。

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

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

因此,假设您有这三个中间件: [a, b, c]并将它们全部传递给 applyMiddleware function。 这是发生的事情:

  1. 首先,每个中间件都使用middlewareAPI API object 调用,它基本上是一个包含原始store.dispatch和 store.getState 的store.getState

     const middlewareAPI = { getState: store.getState, dispatch: store.dispatch } const aInChain = a(middlewareAPI); const bInChain = b(middlewareAPI); const cInChain = c(middlewareAPI);
  2. 其次,我们调用每个中间件,其结果是之前调用中间件的结果。 期待最后一个中间件,它后面没有任何东西,并将原始调度作为输入。

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

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

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

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

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

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

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

Redux 中间件流水线图

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM