【问题标题】:Redux middleware design re: return valuesRedux 中间件设计 re:返回值
【发布时间】:2017-07-28 04:49:48
【问题描述】:

所以我刚刚阅读了 redux 中间件,它听起来很棒。有一件事让我很烦恼——中间件的返回值。

我了解某些中间件实例会返回内容(即redux-promise),而我知道其他中间件(即logging)不会 - 并且只是返回next(action) 的结果。

我的问题是,如果我想使用两个都返回东西的中间件会发生什么 - 它们肯定会互相破坏,我只会得到最外面的中间件的返回值。

express/connect 中间件通过让中间件将其“结果”写入reqres 对象来解决这个问题,但是redux 的解决方案是什么?

编辑

这是我的问题的一个更具体的例子:

我有两个中间件:

  1. 将所有操作延迟 3 秒分派的中间件。这个中间件返回一个函数,可以调用它来取消调度
  2. 返回数字 5 的中间件,因为出于某种原因我需要数字 5。

根据我链接这两个中间件的顺序,我的dispatch(action) 的结果将是延迟取消 fn 或数字 5。但是我如何获得这两个结果?

【问题讨论】:

  • 这就是 Redux 中间件的设计方式。大多数中间件会简单地将它们从next() 收到的任何返回值传回,但是如果中间件愿意,它完全可以返回其他值。这主要归结为 JS 函数只返回一个值。
  • 一个好的答案可能从 Redux Typescript 定义开始:github.com/reactjs/redux/blob/master/index.d.ts
  • 作为参考,这是 Redux cmets 中提到任意返回值行为的评论,顺便说一句:github.com/reduxjs/redux/blob/…

标签: javascript redux middleware redux-promise


【解决方案1】:

您错过了中间件的重点,它是用于消费和调度操作的管道。返回值通常会被忽略。

【讨论】:

    【解决方案2】:

    查看applyMiddleware 上的文档。它解释了中间件要被编写成可组合的,这样它就可以插入到中间件链中,而不必担心在它之前和之后应用的中间件:

    中间件的关键特性是它是可组合的。多种的 中间件可以组合在一起,每个中间件都不需要 了解链中它之前或之后的内容。

    文档很好地解释了要传递到中间件的参数和预期的返回值。

    https://redux.js.org/api/applyMiddleware

    【讨论】:

    • 嗨哟,感谢您的回复!阅读了链接页面,但仍然觉得我的问题没有得到解答。我已经编辑了我原来的问题,以提供一个具体的例子来提高清晰度。谢谢!
    • 我不确定我是否理解您的示例。中间件应该接受两个参数,getStatedispatch,并返回一个返回 next(action) 的函数。每个中间件的中间件签名都是相同的,因此您不会有一个返回 5 的中间件。来自文档:“中间件签名是({ getState, dispatch }) => next => action
    • @YoWakita 我认为 maambmb 指的是 Redux 评论中引用的相同“任意返回”:github.com/reduxjs/redux/blob/…
    【解决方案3】:

    所以下面是一个可运行的脚本,它演示了我正在尝试(但失败)描述的问题。它还包括一个潜在的解决方案(使用中间件包装器)。很想知道是否有更优雅的解决方案......

    var { createStore, applyMiddleware } = require( "redux" );
    var dispatchResult;
    
    // create the results object to be passed along the middleware chain, collecting
    // results as it goes
    const genesis = _store => next => action => {
        next( action );
        return {};
    };
    
    const wrapper = ( key, mware ) => store => next => action => {
    
        // extract the results object by storing the result of next(action)
        // when it is called within the middleware
        var extractedResult;
        function modifiedNext( action ) {
            extractedResult = next( action );
            return extractedResult;
        }
    
        // get the result of this middleware and append it to the results object
        // then pass on said results object...
        var newResult = mware( store )( modifiedNext )( action );
        extractedResult[ key ] = newResult;
        return extractedResult;
    };
    
    // create standard logging middleware
    const logger = store => next => action => {
        let result = next( action );
        console.log( `value is: ${ store.getState() }.`);
        return result;
    };
    
    // create middleware that returns a number
    const gimme = val => _store => next => action => {
        next( action );
        return val;
    };
    
    // create our super simple counter incrementer reduer
    function reducer( state = 0, action ) {
        if( action.type === "INC" )
            return state + 1;
        return state;
    }
    
    
    // first lets try running this without the wrapper:
    dispatchResult = createStore( reducer, applyMiddleware(
        gimme( 4 ),
        logger,
        gimme( 5 )
    ) ).dispatch( { type : "INC" } );
    
    // will return only 4 (the result of the outermost middleware)
    // we have lost the 5 from the gimme(5) middleware
    console.log( dispatchResult );
    
    // now we include the middleware wrapper and genesis middleware
    dispatchResult = createStore( reducer, applyMiddleware(
        wrapper( "g4", gimme( 4 ) ),
        logger,
        wrapper( "g5", gimme( 5 ) ),
        genesis
    ) ).dispatch( { type : "INC" } );
    
    // we will now return { g4 : 4, g5 : 5 }
    // we have preserved the results of both middlewares
    console.log( dispatchResult );
    

    【讨论】:

      猜你喜欢
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多