useQueries 的新 APInotifyOnChangeProps 属性不再接受 "tracked" 作为值notifyOnChangePropsExclusion 已被删除cancelRefetch 的一致行为onSuccess 不再从 setQueryData 调用persistQueryClient 和相应的持久化程序插件不再是实验性的,并且已重命名cancel 方法不再受支持setLogger 已删除queryClient、query 和 mutation 中删除了未记录的方法src/react 目录已重命名为 src/reactjsv4 是一个主要版本,因此需要注意一些重大更改:
您需要卸载/安装依赖项并更改导入:
npm uninstall react-query
npm install @tanstack/react-query
npm install @tanstack/react-query-devtools
npm uninstall react-query
npm install @tanstack/react-query
npm install @tanstack/react-query-devtools
- import { useQuery } from 'react-query' // [!code --]
- import { ReactQueryDevtools } from 'react-query/devtools' // [!code --]
+ import { useQuery } from '@tanstack/react-query' // [!code ++]
+ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' // [!code ++]
- import { useQuery } from 'react-query' // [!code --]
- import { ReactQueryDevtools } from 'react-query/devtools' // [!code --]
+ import { useQuery } from '@tanstack/react-query' // [!code ++]
+ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' // [!code ++]
为了简化导入迁移,v4 附带了一个代码转换工具。
代码转换工具会尽力帮助您迁移重大更改。请仔细检查生成的代码!此外,代码转换工具无法找到某些边缘情况,因此请密切关注日志输出。
您可以通过使用以下一个(或两个)命令轻松应用它:
如果要针对 .js 或 .jsx 文件运行它,请使用以下命令:
npx jscodeshift ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
npx jscodeshift ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
如果要针对 .ts 或 .tsx 文件运行它,请使用以下命令:
npx jscodeshift ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
npx jscodeshift ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/replace-import-specifier.js
请注意,在 TypeScript 的情况下,您需���使用 tsx 作为解析器;否则,代码转换工具将无法正确应用!
**注意:**应用代码转换工具可能会破坏您的代码格式,因此请不要忘记在应用代码转换工具后运行 prettier 和/或 eslint!
**注意:**代码转换工具_仅_更改导入 - 您仍然需要手动安装单独的开发者工具包。
在 v3 中,查询和变更键可以是字符串或数组。在内部,React Query 始终仅使用数组键,并且我们有时会将此公开给使用者。例如,在 queryFn 中,您始终会以数组形式获取键,以便更轻松地使用默认查询函数。
但是,我们并未将此概念贯彻到所有 API 中。例如,当在查询过滤器上使用 predicate 函数时,您将获得原始查询键。如果您使用混合数组和字符串的查询键,这将使使用此类函数变得困难。全局回调也是如此。
为了简化所有 API,我们决定仅将所有键设为数组:
;-useQuery('todos', fetchTodos) + // [!code --]
useQuery(['todos'], fetchTodos) // [!code ++]
;-useQuery('todos', fetchTodos) + // [!code --]
useQuery(['todos'], fetchTodos) // [!code ++]
为了简化此迁移,我们决定提供一个代码转换工具。
代码转换工具会尽力帮助您迁移重大更改。请仔细检查生成的代码!此外,代码转换工具无法找到某些边缘情况,因此请密切关注日志输出。
您可以通过使用以下一个(或两个)命令轻松应用它:
如果要针对 .js 或 .jsx 文件运行它,请使用以下命令:
npx jscodeshift ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
npx jscodeshift ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
如果要针对 .ts 或 .tsx 文件运行它,请使用以下命令:
npx jscodeshift ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
npx jscodeshift ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/codemods/v4/key-transformation.js
请注意,在 TypeScript 的情况下,您需要使用 tsx 作为解析器;否则,代码转换工具将无法正确应用!
**注意:**应用代码转换工具可能会破坏您的代码格式,因此请不要忘记���应用代码转换工具后运行 prettier 和/或 eslint!
随着新的 fetchStatus 的引入以提供更好的离线支持,idle 状态变得无关紧要,因为 fetchStatus: 'idle' 更好地捕获了相同的状态。有关更多信息,请阅读为什么存在两种不同的状态。
这将主要影响尚无任何 data 的 disabled 查询,因为这些查询以前处于 idle 状态:
- status: 'idle' // [!code --]
+ status: 'loading' // [!code ++]
+ fetchStatus: 'idle' // [!code ++]
- status: 'idle' // [!code --]
+ status: 'loading' // [!code ++]
+ fetchStatus: 'idle' // [!code ++]
此外,请查看关于依赖查询的指南
由于此更改,禁用的查询(即使是暂时禁用的查询)将以 loading 状态开始。为了简化迁移,尤其是在需要一个好的标志来知道何时显示加载微调器时,您可以检查 isInitialLoading 而不是 isLoading:
;-isLoading + // [!code --]
isInitialLoading // [!code ++]
;-isLoading + // [!code --]
isInitialLoading // [!code ++]
另请参阅有关禁用查询的指南
useQueries 钩子现在接受一个包含 queries 属性的对象作为其输入。queries 属性的值是一个查询数组(此数组与 v3 中传递给 useQueries 的数组相同)。
;-useQueries([
{ queryKey1, queryFn1, options1 },
{ queryKey2, queryFn2, options2 },
]) + // [!code --]
useQueries({
queries: [
{ queryKey1, queryFn1, options1 },
{ queryKey2, queryFn2, options2 },
],
}) // [!code ++]
;-useQueries([
{ queryKey1, queryFn1, options1 },
{ queryKey2, queryFn2, options2 },
]) + // [!code --]
useQueries({
queries: [
{ queryKey1, queryFn1, options1 },
{ queryKey2, queryFn2, options2 },
],
}) // [!code ++]
为了通过返回 undefined 来实现更新的跳出,我们必须将 undefined 设为非法缓存值。这与 react-query 的其他概念一致,例如,从 initialData 函数返回 undefined 也_不会_设置数据。
此外,通过在 queryFn 中添加日志记录很容易产生 Promise<void> 的错误:
useQuery(['key'], () =>
axios.get(url).then((result) => console.log(result.data)),
)
useQuery(['key'], () =>
axios.get(url).then((result) => console.log(result.data)),
)
这现在在类型级别上是不允许的;在运行时,undefined 将被转换为一个_失败的 Promise_,这意味着您将收到一个 error,该错误也将在开发模式下记录到控制台。
请阅读有关在线/离线支持的新功能公告,以及有关网络模式的专门页面
尽管 React Query 是一个异步状态管理器,可用于任何产生 Promise 的事物,但它最常用于数据获取并与数据获取库结合使用。因此,默认情况下,如果没有网络连接,查询和变更将处于 paused 状态。如果您想选择加���以前的行为,可以全局为查询和变更设置 networkMode: offlineFirst:
new QueryClient({
defaultOptions: {
queries: {
networkMode: 'offlineFirst',
},
mutations: {
networkMode: 'offlineFirst',
},
},
})
new QueryClient({
defaultOptions: {
queries: {
networkMode: 'offlineFirst',
},
mutations: {
networkMode: 'offlineFirst',
},
},
})
notifyOnChangeProps 选项不再接受 "tracked" 值。相反,useQuery 默认跟踪属性。所有使用 notifyOnChangeProps: "tracked" 的查询都应通过删除此选项进行更新。
如果您想在任何查询中绕过此行为以模拟 v3 的默认行为(即每当查询更改时重新渲染),notifyOnChangeProps 现在接受 "all" 值以选择退出默认的智能跟踪优化。
在 v4 中,notifyOnChangeProps 默认为 v3 的 "tracked" 行为,而不是 undefined。既然 "tracked" 是 v4 的默认行为,那么包含此配置选项就不再有意义了。
cancelRefetch 选项可以传递给所有命令式获取查询的函数,即:
除了 fetchNextPage 和 fetchPreviousPage,此标志默认为 false,这是不一致且可能存在问题的:如果在变更后调用 refetchQueries 或 invalidateQueries,如果先前缓慢的获取仍在进行中,则可能无法产生最新结果,因为此重新获取将被跳过。
我们认为,如果某个查询被您编写的某些代码主动重新获取,则默认情况下它应该重新启动获取。
因此,此标志现在对于上述所有方法都默认为 true。这也意味着如果您连续两次调用 refetchQueries 而不等待它,它现在将取消第一次获取并使用第二次获取重新启动它:
queryClient.refetchQueries({ queryKey: ['todos'] })
// 这将中止先前的重新获取并开始新的获取
queryClient.refetchQueries({ queryKey: ['todos'] })
queryClient.refetchQueries({ queryKey: ['todos'] })
// 这将中止先前的重新获取并开始新的获取
queryClient.refetchQueries({ queryKey: ['todos'] })
您可以通过显式传递 cancelRefetch:false 来选择退出此行为:
queryClient.refetchQueries({ queryKey: ['todos'] })
// 这不会中止先前的重新获取 - 它只会被忽略
queryClient.refetchQueries({ queryKey: ['todos'] }, { cancelRefetch: false })
queryClient.refetchQueries({ queryKey: ['todos'] })
// 这不会中止先前的重新获取 - 它只会被忽略
queryClient.refetchQueries({ queryKey: ['todos'] }, { cancelRefetch: false })
注意:对于自动触发的获取(例如,因为查询挂载或因为窗口焦点重新获取),行为没有变化。
查询过滤器是一个具有某些条件的对象,用于匹配查询。从历史上看,过滤器选项大多是布尔标志的组合。但是,组合这些标志可能会导致不可能的状态。具体来说:
active?: boolean
- 设置为 true 时,它将匹配活动查询。
- 设置为 false 时,它将匹配非活动查询。
inactive?: boolean
- 设置为 true 时,它将匹配非活动查询。
- 设置为 false 时,它将匹配活动查询。
active?: boolean
- 设置为 true 时,它将匹配活动查询。
- 设置为 false 时,它将匹配非活动查询。
inactive?: boolean
- 设置为 true 时,它将匹配非活动查询。
- 设置为 false 时,它将匹配活动查询。
这些标志一起使用时效果不佳,因为它们是互斥的。从描述来看,将两个标志都设置为 false 可能会匹配所有查询,或者不匹配任何查询,这没有多大意义。
对于 v4,这些过滤器已合并为一个过滤器,以更好地显示意图:
- active?: boolean // [!code --]
- inactive?: boolean // [!code --]
+ type?: 'active' | 'inactive' | 'all' // [!code ++]
- active?: boolean // [!code --]
- inactive?: boolean // [!code --]
+ type?: 'active' | 'inactive' | 'all' // [!code ++]
过滤器默认为 all,您可以选择仅匹配 active 或 inactive 查询。
queryClient.invalidateQueries 有两个额外的类似标志:
refetchActive: Boolean
- 默认为 true
- 设置为 false 时,与重新获取谓词匹配且通过 useQuery 及其相关项主动呈现的查询
将不会在后台重新获取,而只会被标记为无效。
refetchInactive: Boolean
- 默认为 false
- 设置为 true 时,与重新获取谓词匹配且未通过 useQuery 及其相关项呈现的查询
将被标记为无效并在后台重新获取
refetchActive: Boolean
- 默认为 true
- 设置为 false 时,与重新获取谓词匹配且通过 useQuery 及其相关项主动呈现的查询
将不会在后台重新获取,而只会被标记为无效。
refetchInactive: Boolean
- 默认为 false
- 设置为 true 时,与重新获取谓词匹配且未通过 useQuery 及其相关项呈现的查询
将被标记为无效并在后台重新获取
出于同样的原因,这些也已合并:
- refetchActive?: boolean // [!code --]
- refetchInactive?: boolean // [!code --]
+ refetchType?: 'active' | 'inactive' | 'all' | 'none' // [!code ++]
- refetchActive?: boolean // [!code --]
- refetchInactive?: boolean // [!code --]
+ refetchType?: 'active' | 'inactive' | 'all' | 'none' // [!code ++]
此标志默认为 active,因为 refetchActive 默认为 true。这意味着我们还需要一种方法来告诉 invalidateQueries 完全不重新获取,这就是为什么这里也允许第四个选项 (none)。
这让许多人感到困惑,并且如果在 onSuccess 内部调用 setQueryData,还会产生无限循环。当与 staleTime 结合使用时,这也是一个常见的错误来源,因为如果仅从缓存中读取数据,则_不会_调用 onSuccess。
与 onError 和 onSettled 类似,onSuccess 回调现在与发出的请求相关联。没有请求 -> 没有回调。
如果您想侦听 data 字段的更改,最好使用 useEffect 来执行此操作,其中 data 是依赖项数组的一部分。由于 React Query 通过结构共享确保数据稳定,因此效果不会在每次后台重新获取时执行,而仅在数据内部发生更改时执行:
const { data } = useQuery({ queryKey, queryFn })
React.useEffect(() => mySideEffectHere(data), [data])
const { data } = useQuery({ queryKey, queryFn })
React.useEffect(() => mySideEffectHere(data), [data])
插件 createWebStoragePersistor 和 createAsyncStoragePersistor 已分别重命名为 createSyncStoragePersister 和 createAsyncStoragePersister。persistQueryClient 中的接口 Persistor 也已重命名为 Persister。有关此更改的动机,请查看此 stackexchange。
由于这些插件不再是实验性的,因此它们的导入路径也已更新:
- import { persistQueryClient } from 'react-query/persistQueryClient-experimental' // [!code --]
- import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental' // [!code --]
- import { createAsyncStoragePersistor } from 'react-query/createAsyncStoragePersistor-experimental' // [!code --]
+ import { persistQueryClient } from '@tanstack/react-query-persist-client' // [!code ++]
+ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code ++]
+ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code ++]
- import { persistQueryClient } from 'react-query/persistQueryClient-experimental' // [!code --]
- import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental' // [!code --]
- import { createAsyncStoragePersistor } from 'react-query/createAsyncStoragePersistor-experimental' // [!code --]
+ import { persistQueryClient } from '@tanstack/react-query-persist-client' // [!code ++]
+ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code ++]
+ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code ++]
旧的 cancel 方法允许您在 Promise 上定义一个 cancel 函数,该函数随后被库用于支持查询取消,现已删除。我们建议使用较新的 API(从 v3.30.0 开始引入)进行查询取消,该 API 在内部使用 AbortController API 并为您提供一个 AbortSignal 实例 以供您的查询函数支持查询取消。
类型现在需要使用 TypeScript v4.1 或更高版本
从 v4 开始,React Query 针对现代浏览器进行了优化。我们更新了我们的 browserslist 以生成更现代、性能更好且更小的捆绑包。您可以在此处阅读有关要求的信息。
以前可以通过调用 setLogger 来全局更改记录器。在 v4 中,该函数在创建 QueryClient 时被一个可选字段取代。
- import { QueryClient, setLogger } from 'react-query'; // [!code --]
+ import { QueryClient } from '@tanstack/react-query'; // [!code ++]
- setLogger(customLogger) // [!code --]
- const queryClient = new QueryClient(); // [!code --]
+ const queryClient = new QueryClient({ logger: customLogger }) // [!code ++]
- import { QueryClient, setLogger } from 'react-query'; // [!code --]
+ import { QueryClient } from '@tanstack/react-query'; // [!code ++]
- setLogger(customLogger) // [!code --]
- const queryClient = new QueryClient(); // [!code --]
+ const queryClient = new QueryClient({ logger: customLogger }) // [!code ++]
在 v3 中,React Query 会默认缓存查询结果 5 分钟,然后手动进行垃圾回收。此默认值也适用于服务器端的 React Query。
这导致了高内存消耗和等待此手动垃圾回收完成的挂起进程。在 v4 中,默认情况下,服务器端的 cacheTime 现在设置为 Infinity,有效地禁用了手动垃圾回收(NodeJS 进程将在请求完成后清除所有内容)。
此更改仅影响服务器端 React Query 的用户,例如 Next.js。如果您手动设置 cacheTime,则不会受到影响(尽管您可能希望镜像行为)。
从 v4 开始,react-query 将不再在生产模式下将错误(例如,获取失败)记录到控制台,因为这让许多人感到困惑。 错误仍将在开发模式下显示。
React Query 现在支持 package.json "exports",并且与 Node 对 CommonJS 和 ESM 的本机解析完全兼容。我们预计这对于大多数用户来说不会是一个重大更改,但这会将您可以导入到项目中的文件限制为我们官方支持的入口点。
手动订阅 QueryCache 始终会为您提供 QueryCacheNotifyEvent,但这对于 MutationCache 并非如此。我们简化了行为并相应地调整了事件名称。
- type: 'queryAdded' // [!code --]
+ type: 'added' // [!code ++]
- type: 'queryRemoved' // [!code --]
+ type: 'removed' // [!code ++]
- type: 'queryUpdated' // [!code --]
+ type: 'updated' // [!code ++]
- type: 'queryAdded' // [!code --]
+ type: 'added' // [!code ++]
- type: 'queryRemoved' // [!code --]
+ type: 'removed' // [!code ++]
- type: 'queryUpdated' // [!code --]
+ type: 'updated' // [!code ++]
MutationCacheNotifyEvent 使用与 QueryCacheNotifyEvent 相同的类型。
注意:这仅在您通过 queryCache.subscribe 或 mutationCache.subscribe 手动订阅缓存时才相关
从版本 3.22.0 开始,水合工具已移至 React Query 核心。在 v3 中,您仍然可以使用 react-query/hydration 中的旧导出,但这些导出已在 v4 中删除。
- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration' // [!code --]
+ import { dehydrate, hydrate, useHydrate, Hydrate } from '@tanstack/react-query' // [!code ++]
- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration' // [!code --]
+ import { dehydrate, hydrate, useHydrate, Hydrate } from '@tanstack/react-query' // [!code ++]
QueryClient 上的 cancelMutations 和 executeMutation 方法未记录且未在内部使用,因此我们删除了它们。由于它只是 mutationCache 上可用方法的包装器,因此您仍然可以使用 executeMutation 的功能
- executeMutation< // [!code --]
- TData = unknown, // [!code --]
- TError = unknown, // [!code --]
- TVariables = void, // [!code --]
- TContext = unknown // [!code --]
- >( // [!code --]
- options: MutationOptions<TData, TError, TVariables, TContext> // [!code --]
- ): Promise<TData> { // [!code --]
- return this.mutationCache.build(this, options).execute() // [!code --]
- } // [!code --]
- executeMutation< // [!code --]
- TData = unknown, // [!code --]
- TError = unknown, // [!code --]
- TVariables = void, // [!code --]
- TContext = unknown // [!code --]
- >( // [!code --]
- options: MutationOptions<TData, TError, TVariables, TContext> // [!code --]
- ): Promise<TData> { // [!code --]
- return this.mutationCache.build(this, options).execute() // [!code --]
- } // [!code --]
此外,query.setDefaultOptions 已被删除,因为它也未使用。mutation.cancel 已被删除,因为它实际上并未取消传出请求。
以前,React Query 有一个名为 react 的目录,它从 react 模块导入。这可能会导致某些 Jest 配置出现问题,从而在运行测试时导致如下错误:
TypeError: Cannot read property 'createContext' of undefined
TypeError: Cannot read property 'createContext' of undefined
重命名目录后,此问题不再存在。
如果您直接在项目中从 'react-query/react' 导入任何内容(而不是仅从 'react-query' 导入),则需要更新您的导入:
- import { QueryClientProvider } from 'react-query/react'; // [!code --]
+ import { QueryClientProvider } from '@tanstack/react-query/reactjs'; // [!code ++]
- import { QueryClientProvider } from 'react-query/react'; // [!code --]
+ import { QueryClientProvider } from '@tanstack/react-query/reactjs'; // [!code ++]
v4 带来了一系列很棒的新功能:
React 18 于今年早些时候发布,v4 现在对其以及它带来的新并发功能提供了一流的支持。
在 v3 中,React Query 始终会触发查询和变更,但随后会假设如果您想重试,则需要连接到互联网。这导致了一些令人困惑的情况:
对于 v4,React Query 引入了一种新的 networkMode 来解决所有这些问题。有关新的网络模式的更多信息,请阅读专门的页面。
React Query 默认“跟踪”查询属性,这应该会为您带来不错的渲染优化提升。该功能自 v3.6.0 起就已存在,现已成为 v4 的默认行为。
当使用 setQueryData 的函数式更新程序形式时,您现在可以通过返回 undefined 来跳出更新。如果将 undefined 作为 previousValue 提供给您,这将很有用,这意味着当前不存在缓存条目,并且您不想/无法创建一个,例如在切换待办事项的示例中:
queryClient.setQueryData(['todo', id], (previousTodo) =>
previousTodo ? { ...previousTodo, done: true } : undefined,
)
queryClient.setQueryData(['todo', id], (previousTodo) =>
previousTodo ? { ...previousTodo, done: true } : undefined,
)
现在也可以像查询一样自动对变更进行垃圾回收。变更的默认 cacheTime 也设置为 5 分钟。
现在可以指定自定义上下文以将钩子与其匹配的 Provider 配对。当组件树中可能存在多个 React Query Provider 实例时,这至关重要,并且您需要确保您的钩子使用正确的 Provider 实例。
一个例子:
// 我们的第一个数据包:@my-scope/container-data
const context = React.createContext<QueryClient | undefined>(undefined)
const queryClient = new QueryClient()
export const useUser = () => {
return useQuery(USER_KEY, USER_FETCHER, {
context,
})
}
export const ContainerDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}
// 我们的第一个数据包:@my-scope/container-data
const context = React.createContext<QueryClient | undefined>(undefined)
const queryClient = new QueryClient()
export const useUser = () => {
return useQuery(USER_KEY, USER_FETCHER, {
context,
})
}
export const ContainerDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}
// 我们的第二个数据包:@my-scope/my-component-data
const context = React.createContext<QueryClient | undefined>(undefined)
const queryClient = new QueryClient()
export const useItems = () => {
return useQuery(ITEMS_KEY, ITEMS_FETCHER, {
context,
})
}
export const MyComponentDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}
// 我们的第二个数据包:@my-scope/my-component-data
const context = React.createContext<QueryClient | undefined>(undefined)
const queryClient = new QueryClient()
export const useItems = () => {
return useQuery(ITEMS_KEY, ITEMS_FETCHER, {
context,
})
}
export const MyComponentDataProvider = ({
children,
}: {
children: React.ReactNode
}) => {
return (
<QueryClientProvider client={queryClient} context={context}>
{children}
</QueryClientProvider>
)
}
// 我们的应用程序
import { ContainerDataProvider, useUser } from "@my-scope/container-data";
import { AppDataProvider } from "@my-scope/app-data";
import { MyComponentDataProvider, useItems } from "@my-scope/my-component-data";
<ContainerDataProvider> // <-- 使用其自己的 React Query 提供程序提供容器数据(例如“用户”)
...
<AppDataProvider> // <-- 使用其自己的 React Query 提供程序提供应用程序数据(在此示例中未使用)
...
<MyComponentDataProvider> // <-- 使用其自己的 React Query 提供程序提供组件数据(例如“项目”)
<MyComponent />
</MyComponentDataProvider>
...
</AppDataProvider>
...
</ContainerDataProvider>
// 上面“DataProvider”组件提供的钩子示例:
const MyComponent = () => {
const user = useUser() // <-- 使用 ContainerDataProvider 中指定的上下文。
const items = useItems() // <-- 使用 MyComponentDataProvider 中指定的上下文
...
}
// 我们的应用程序
import { ContainerDataProvider, useUser } from "@my-scope/container-data";
import { AppDataProvider } from "@my-scope/app-data";
import { MyComponentDataProvider, useItems } from "@my-scope/my-component-data";
<ContainerDataProvider> // <-- 使用其自己的 React Query 提供程序提供容器数据(例如“用户”)
...
<AppDataProvider> // <-- 使用其自己的 React Query 提供程序提供应用程序数据(在此示例中未使用)
...
<MyComponentDataProvider> // <-- 使用其自己的 React Query 提供程序提供组件数据(例如“项目”)
<MyComponent />
</MyComponentDataProvider>
...
</AppDataProvider>
...
</ContainerDataProvider>
// 上面“DataProvider”组件提供的钩子示例:
const MyComponent = () => {
const user = useUser() // <-- 使用 ContainerDataProvider 中指定的上下文。
const items = useItems() // <-- 使用 MyComponentDataProvider 中指定的上下文
...
}