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

Posted

技术标签:

【中文标题】如何使 thunk 独立于状态形状以使其可移植?【英文标题】:How to make thunks independent from state shape to make them portable? 【发布时间】:2016-05-19 14:19:47 【问题描述】:

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

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

假设我的根减速器如下所示:

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 并需要读取应用状态的动作创建者,因为现在所有内容都包含在“myApp”状态切片中。

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

到目前为止想到的一些技巧/想法:

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

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

有什么想法/建议吗?您将如何解决此类问题?

【问题讨论】:

【参考方案1】:

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

例如:

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

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

这使得操作完全可重用,缺点是您现在必须在其他地方拥有该信息。还有什么地方?如果方便的话,在你的组件内部使用this.context.store,或者通过propsconnect,或者更好的是,为你的特定应用程序设置包装器操作,所以:

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

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

【讨论】:

这实际上是一个我还没有想过的好主意,谢谢!我会玩一会儿,然后回来接受你的回答,并最终用我的最终解决方案更新我最初的问题。 这也是我的建议。

以上是关于如何使 thunk 独立于状态形状以使其可移植?的主要内容,如果未能解决你的问题,请参考以下文章

javascript 在元素周围添加锚标记以使其可单击

如何反转 QSlider 元素的 Ticklabels 以及如何使其可点击?

jquery-select2 - 将 select2 添加到现有的下拉代码中以使其可搜索

如何打包 python 应用程序以使其可 pip 安装?

C++中如何重载输入输出流运算符使其可用于矩阵的输入输出?

jQuery DataTable - 添加新行有效,但无法使其可编辑(可编辑)