Eva*_*van 16 reactjs react-redux redux-toolkit rtk-query
我认为我缺少有关 Redux 和 RTK 查询工具的一些东西。我还为此使用 RTK Query OpenAPI codegen。
现在我有一个如下所示的 API ->
export const api = generatedApi.enhanceEndpoints({
endpoints: {
getMaterials: {
transformResponse: response => normalize(response),
},
},
})
Run Code Online (Sandbox Code Playgroud)
这在我的组件中很好地返回了标准化数据:
const Materials = () => {
const { data, isLoading, error } = useGetMaterialsQuery()
/*
Cool this gives me data back like:
{
[id]: {
id,
prop1: 'blah',
prop2: 'blah2'
}
}
*/
console.log(data)
// but now I want to structure this data differently using selector
const newDataStructure = useSelector(addSomeMetaDataAndStructureDifferentlySelector)
return <MyComponent structuredData={newDataStructure} />
}
Run Code Online (Sandbox Code Playgroud)
但是当我查看该选择器中的状态时,它看起来像:
当在选择器中时,我真的想使用类似 -> 的东西
const addSomeMetaDataAndStructureDifferentlySelector = state =>
// create new data structure from state.materials.byId that I will pass to `MyComponent`
Run Code Online (Sandbox Code Playgroud)
我的商店现在看起来像这样 ->
import { configureStore } from '@reduxjs/toolkit'
import { setupListeners } from '@reduxjs/toolkit/query'
import { api } from 'gen/rtk-openapi'
// import materialsReducer from 'state/materials/materialsSlice'
const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
},
middleware: getDefaultMiddleware =>
getDefaultMiddleware().concat(api.middleware),
})
setupListeners(store.dispatch)
export default store
Run Code Online (Sandbox Code Playgroud)
那么我是否需要data直接将 from传递useGetMaterialsQuery到函数中并对其进行转换?
或者我可以以某种方式创建一个新的减速器切片,以某种方式正确初始化数据,以便我可以state.materials.byId在选择器中访问?
或者我从根本上错过了一些东西?
phr*_*hry 20
您错过了重要的一点:RTK-Query 不是标准化缓存,而是文档缓存。
它使用请求参数作为缓存键来缓存您的端点以及对这些端点的每个请求。这些响应中的每一个都被视为“文档”并单独缓存。
这似乎是一个缺点,但作为一个通用库,做一个真正的“标准化”缓存几乎是不可能的,特别是对于像 REST api 这样不明确的东西。即使对于 GraphQL 来说,这也是一个非常困难的问题,甚至专门针对 GraphQL 的解决方案(如 apollo)也有很多问题,并且最终会产生大量手写代码来处理集合中添加/删除等情况。
因此,最后,您有两个选择:手动编写自己的规范化缓存解决方案,明确适合您的数据结构或使用文档缓存。
在大多数情况下,文档缓存就足够了。这就是 RTK-Query 的用武之地,它试图为您提供尽可能多的工具来保持文档之间的数据“同步”:自动重新获取以及您希望避免执行手动乐观更新来操作特定缓存条目的选项。
一般来说,我建议不要将数据复制到手写切片中。这样您将失去 RTK-Query 的许多好处,例如订阅跟踪和 60 秒后没有更多组件使用值后的自动缓存清理。在使用 Redux 和手写切片一段时间后,这听起来可能不太常见,但它在大多数情况下都工作得很好 - 代码少了很多。
至于如何使用:一般来说,你只需useGetMaterialsQuery()在所有需要该材料的组件中调用你的组件,然后在你的组件中过滤掉你需要的东西,或者使用选项selectFromResult来选择你真正需要的东西。
| 归档时间: |
|
| 查看次数: |
19770 次 |
| 最近记录: |