如何使thunks独立于状态以使其可移植?

时间:2016-02-09 14:37:02

标签: javascript redux redux-thunk

我使用React和Redux开发了一个小型的独立Web应用程序,该应用程序托管在自己的Web服务器上。我们现在想要将此应用程序的大部分内容重用/集成到另一个React / Redux Web应用程序中。

理论上,这应该可以很好地工作,因为我的所有React组件,reducer和大多数动作创建者都是纯粹的。但我有一些动作创建者返回依赖于应用程序状态的thunk。他们可能会调度异步或同步操作,但这不是问题所在。

假设我的root reducer看起来像这样:

const myAppReducer = combineReducers({
    foo: fooReducer,
    bar: barReducer,
    baz: bazReducer
});

而我最复杂的动作创建者依赖于许多状态切片(幸运的是只有少数几个):

const someAction = function () {
    return (dispatch, getState) => {
        const state = getState();

        if (state.foo.someProp && !state.bar.anotherProp) {
            dispatch(fetchSomething(state.baz.currentId);
        } else {
            dispatch(doSomethingSynchronous());
        }
    };
}

现在的问题是我的动作创建者希望一切都在状态对象的根目录之内。但是如果我们想将这个应用程序集成到另一个redux应用程序中,我们必须使用自己的密钥安装我的appReducer:

// The otherAppReducer that wants to integrate my appReducer
const otherAppReducer = combineReducers({
    ....
    myApp: myAppReducer
});

这显然打破了我的动作创建者返回thunk并需要读取app状态,因为现在所有内容都包含在“myApp”状态切片中。

我做了很多研究并思考过去几天如何正确解决这个问题,但似乎我是第一个尝试将基于Redux的应用程序集成到另一个基于Redux的应用程序中的人。

到目前为止,我想到了一些黑客/想法:

  • 创建我自己的thunk类型,这样我就可以在自定义thunk中间件中进行instanceof检查,并让它通过我的thunks自定义getState函数,然后返回正确的状态切片。
  • 使用自己的密钥安装我的根减速器,并使我的thunk依赖于该密钥。

到目前为止,我认为最好的方法是创建自己的自定义中间件,但我不满意其他应用程序现在依赖于我的中间件和自定义thunk类型的事实。我认为必须采用更通用的方法。

任何想法/建议?你会如何解决这类问题?

1 个答案:

答案 0 :(得分:3)

您认为不依赖于store.getState()吗?我会将操作与应用程序状态完全分离,并从调用操作的位置获取所需的数据。

例如:

const someAction = function (someProp, anotherProp, currentId) {
    return dispatch => {

        if (someProp && !anotherProp) {
            dispatch(fetchSomething(currentId);
        } else {
            dispatch(doSomethingSynchronous());
        }
    };
}

这使得这些操作完全可以重复使用,您必须在其他地方获得该信息。还有哪里?如果方便的话,使用this.context.storeprops使用connect,或者更好,通过为特定应用程序执行包装操作,在组件内部,所以:

const someApplicationAction = () => {
  return (dispatch, getState) => {
    const { foo, bar, baz } = getState();

    dispatch(someGenericAction(foo.someProp, bar.anotherProp, baz.currentID));
  };
}