如何跨组件缓存昂贵的自定义挂钩函数(源自 RTK 查询结果)?

发布于 2025-01-14 05:03:56 字数 773 浏览 2 评论 0原文

我已将 RTK 查询设置为应用程序中的 API 层。这替换了之前存储在 redux 中用于构建选择器的数据(使用来自重新选择的 CreateSelector)。

现在有了 RTK 查询,一切都在钩子中,所以我很自然地尝试将 CreateSelector 中的逻辑移动到来自 RTK 查询结果的各种钩子,如下所示:

useSelectStoreDetailedData = () => {
    const {storesData} = useListStoresQuery()
    const {productsData} = useListProductsQuery()
    const {pricesData} = useListPricesQuery()
    return useMemo(()=> runExpensiveFunc(storesData, productsData, pricesData), 
     [storesData, productsData, pricesData])
}

当 1 个组件调用此钩子时,这可以正常工作,但如果许多组件需要此数据,每个组件调用钩子(即useSelectStoreDetailedData())都会导致数据从头开始重新处理,因为它正在挂载钩子的另一个实例。由于这是一项非常昂贵的操作,因此这会导致应用程序明显变慢。

我尝试过使用 lodash memoize 函数来获取这个昂贵的函数并记住它,但这也是确定相等性的昂贵操作。

是否有更好的模式来跨组件共享这种源自 api 的计算?

I have set up RTK Query as an API layer within my application. This replaced data previously stored in redux which was being used to build selectors (using CreateSelector from reselect).

Now with RTK Query, everything is in hooks, so naturally I attempted to move the logic in CreateSelector to various hooks being sourced with RTK Query results like so:

useSelectStoreDetailedData = () => {
    const {storesData} = useListStoresQuery()
    const {productsData} = useListProductsQuery()
    const {pricesData} = useListPricesQuery()
    return useMemo(()=> runExpensiveFunc(storesData, productsData, pricesData), 
     [storesData, productsData, pricesData])
}

This works fine when 1 component is calling this hook, but if many components need this data, each component making a call to the hook (i.e. useSelectStoreDetailedData()) causes the data to be reprocessed from scratch since it's mounting another instance of the hook. Since it's a very expensive operation, this is causing the application to visibly slow down.

I've tried taking this expensive function and memoizing it using lodash memoize function but it's also a costly operation to determine equality.

Is there some better pattern for sharing this api-sourced computation across components?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

面犯桃花 2025-01-21 05:03:56

您只需使用reselect选择器即可。

const selector = createSelector(...)


useSelectStoreDetailedData = () => {
    const {storesData} = useListStoresQuery()
    const {productsData} = useListProductsQuery()
    const {pricesData} = useListPricesQuery()
    return selector(storesData, productsData, pricesData)
}

You could just use your reselect selector.

const selector = createSelector(...)


useSelectStoreDetailedData = () => {
    const {storesData} = useListStoresQuery()
    const {productsData} = useListProductsQuery()
    const {pricesData} = useListPricesQuery()
    return selector(storesData, productsData, pricesData)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文