我可以跨多个组件订阅过滤后的 RTK 查询数据结果吗?

pau*_*llc 3 javascript reactjs redux redux-toolkit rtk-query

我有一系列组件,它们都使用从 RTK 查询响应派生的数据。虽然源自具有相同查询参数的相同响应,但每个组件都需要数据通过一组相对昂贵的客户端过滤器(其参数是 redux 存储切片属性),这些过滤器对于每个组件来说可能不相同。然而,所有组件都要求数据至少通过两个特定的过滤器。这种关系如下图所示:

是否可以在通过特定过滤器/过滤器组转换数据订阅数据?

在此输入图像描述

我考虑过的方法:

  • 在所有组件中使用查询,应用某些 useEffect 或 useMemo 中所需的过滤器。这不是优选的,因为这意味着至少 2 个过滤器被复制 nComponents 次。
  • 使用 createSliceextraReducers选项并监听查询完成,然后执行过滤操作。这工作正常,因为我可以在减速器中使用过滤器参数,但我相信一旦过滤器参数更新但查询数据保持不变,我就无法使用新参数重复操作。
  • 订阅一个组件,在每个相应的过滤阶段之后将数据发布到切片,为每个组件订阅相应的数据。这就是我目前实现的方式,但它并不理想,因为它将我希望避免的组件耦合在一起,使任意选择的一个组件膨胀,并产生频繁的大型状态操作,从而减慢我的应用程序的速度。
  • 提高对共享祖先组件的查询订阅,然后将数据作为 props 传递。这并不理想,因为这些组件相对于它们共同的祖先处于不同的深度,我想这会导致至少对某些组件进行支撑钻孔。
  • 使用 React context 与相应组件共享前 2 个过滤器操作的结果。还没有研究这么多;它可以与查询订阅一起使用吗?

直觉上,我认为在 API 结果和组件的订阅数据之间作为中间件运行的回调是理想的。我知道 API 切片中可定义的transformResponse选项,但我认为它对于这种情况是不合适或不可能的。

const queryResult = endpointName.useQuery(args, filterArgs, (data, filterArgs) => {
    return data.performSomeSharedFilterOperationHere(filterArgs);
    } 
);
Run Code Online (Sandbox Code Playgroud)

理想情况下,当查询参数更改或过滤器参数更改时,数据将更新。我想这和简单的 useEffect 实现之间的区别在于,在 useEffect 场景中,数据不是“共享”的,并且过滤器操作发生 nSubscribedComponents 次。

RTK 中是否有任何内容可以实现我正在寻求的行为?

mar*_*son 6

我认为这里正确的答案是使用查询挂钩中的选项selectFromResult

创建以下重新选择选择器:


const selectFilter1 = createSelector(
  // Start by taking the actual response data as its input
  (inputData) => inputData,
  (data) => // magically transform here
)

const selectFilter2 = createSelector(
  selectFilter1,
  (filteredData) => // magically transform here
)

// repeat for filters 2 and 3
Run Code Online (Sandbox Code Playgroud)

然后,在组件中:


const selectFilter1 = createSelector(
  // Start by taking the actual response data as its input
  (inputData) => inputData,
  (data) => // magically transform here
)

const selectFilter2 = createSelector(
  selectFilter1,
  (filteredData) => // magically transform here
)

// repeat for filters 2 and 3
Run Code Online (Sandbox Code Playgroud)

这些组件将共享相同的选择器实例,因此每次调用选择器时都result.data应该传入相同的引用,因此计算应该被记住。前几个选择器应该记住它们的结果,因此selectFilter3只需selectFilter2在 的结果发生变化等时重新计算。