【问题标题】:Redux middleware change state before next()Redux 中间件在 next() 之前更改状态
【发布时间】:2016-05-13 19:58:07
【问题描述】:

我想在调用next() 之前修改状态,以便在中间件获得新状态之后应用的每个reducer。 有可能吗?怎么样?

我想到的唯一想法很老套,应该是这样的:

export const myMiddleware = (store) => (next) => (action) => {
    const oldReducer = ????
    store.replaceReducer(myReducer);
    store.dispatch(action);
    const newState = store.getState();
    store.replaceReducer(oldReducer);
    return next(newState);
}

由于我没有看到任何获取当前reducer的方法,所以应该以任何方式将其提供给中间件:

export const myMiddleware = (oldReducer) => (store) => (next) => (action) => {
   ...
}

const store = createStore(originalReducer, applyMiddleware(myMiddleware(originalReducer)));

这似乎更骇人听闻!

主要目的是构建一个包,映射一个动作对象 (action.payload) 和存储 state 中的一个路径 (action.meta)。在这种情况下,reducer 分布在一个 npm 包中,因此应该以某种方式“链接”它。所以现在reducer正在检测payload中是否有路径和对象,并尝试从中减少新的状态。

最糟糕的解决方案是指示用户从他们自己的reducer 调用reducer,就在reducer 内部的任何其他操作之前。这不是一个固定的模式。所以起初,我在想一个尽可能不可知的中间件,它可以自动完成工作。这就是为什么我尽可能尝试从中间件修改状态。

【问题讨论】:

    标签: javascript redux middleware react-redux


    【解决方案1】:

    您可能不想从中间件中调用单个 reducer。听起来您正在将应该是多个顺序操作的内容压缩为单个操作,这就是导致您出现问题的原因。如果您使用 redux-saga 之类的东西来管理操作链,您可能会很容易地完成您正在寻找的东西。

    这是一个使用 redux-saga 管理一系列动作的基本示例:

    import { takeEvery } from 'redux-saga'
    import { put } from 'redux-saga/effects'
    
    export function * watchForSomeAction () {
      // Every time SOME_ACTION is dispatched, doSomethingElse() will be called
      // with the action as its argument
      yield * takeEvery('SOME_ACTION', doSomethingElse)
    }
    
    export function * doSomethingElse (action) {
      // put() is redux-saga's way of dispatching actions
      yield put({ type: 'ANOTHER_ACTION', payload: action.payload })
    }
    

    这个例子只是监视SOME_ACTION,当它发生时,它调度ANOTHER_ACTION。通过这样的方式,您可以确保 ANOTHER_ACTION 的减速器正在处理由 SOME_ACTION 的减速器产生的新状态。

    【讨论】:

    • 谢谢,我面临的情况是我正在构建一个包,该包在immutable-js state 中映射一个动作对象 (payload) 和一个路径 (action.meta) .在这种情况下,reducer 分布在一个包中,因此应该以某种方式“链接”它。起初我以为我在想一个尽可能不可知的中间件。所以这就是为什么我尽可能尝试从中间件修改状态。
    • 啊,好的。那么从中间件中简单地调度一个动作是否有意义?你的包用户必须将你的包的 reducer 添加到他们的 combineReducers() 中,但这对于修改状态的包来说是正常的。还是我误解了你的目标?
    • 你是对的,这不是目标。如果用户添加了包reducer,它将无法修改整个reducer,其意图是:构造一个帮助函数,在用户继续操作之前修改用户状态。将是一种 express node.js 中间件,在下一个中间件/用户函数之前解析参数。
    • 对不起,我还是不明白。你能提供一个你想要的 API 和想要的结果的例子吗?
    • 好的,现在我可以将链接发送到我想要实现的目标:github.com/appfeel/path-reducer 我也会在 redux repo 中询问,因为我一直在查看 redux 代码,似乎有暂时没有解决办法
    猜你喜欢
    • 2020-01-29
    • 2020-01-30
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2021-11-18
    • 2018-05-21
    相关资源
    最近更新 更多