2016-05-13 59 views
1

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

这使我心中唯一的想法是非常哈克,并会是这样的:

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

由于我没有看到任何方法来获得当前的减速,应该给予中间件以任何方式:

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

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

这似乎更加hacky!

主要目的是构建一个程序包,该程序包在店铺state中映射操作对象(action.payload)和路径(action.meta)。在这种情况下,reducer分布在一个npm包中,因此应该以某种方式“链接”。因此,减速器正在检测有效载荷内是否存在路径和对象,并试图从中减少新状态。

最糟糕的解决方案是指示用户在减速器内的任何其他动作之前,从其自己的减速器调用减速器。这不是一个坚实的模式。所以起初,我在尽可能不知道中间件的情况下自动完成这项工作。这就是为什么我想尽可能从中间件修改状态的原因。

回答

0

您可能不希望从中间件内部调用个别减速器。这听起来像是你应该将多个顺序操作集中到一个单一的操作中,这是什么导致你的问题。如果您使用类似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的减速器产生的新状态。

+0

谢谢,我面临的情况是,我正在构建一个将一个action对象('payload')和一个路径('action.meta')映射到'immutable-js''状态'的包。在这种情况下,减速器分布在一个包中,所以它应该以某种方式“链接”。起初我以为我在尽可能不知道中间件。所以这就是为什么我想尽可能从中间件修改状态的原因。 – Miquel

+0

啊,好的。简单地从中间件发出一个动作是否有意义?你的软件包用户必须将你的软件包的reducer添加到他们的combineReducers()中,但这对修改状态的软件包来说是正常的。还是我误解你的目标? –

+0

你是对的,这不是目标。如果用户添加包缩减器,它将无法修改整个缩减器,这是为了:在用户继续执行其操作之前构造一个帮助器函数,该函数修改用户状态。会是一种'express node.js'中间件,在下一个中间件/用户函数之前解析参数。 – Miquel