mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-23 04:02:10 +08:00
refactor: migrate query cache to swr
This commit is contained in:
+1
-1
@@ -43,7 +43,6 @@
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@mui/icons-material": "^9.0.1",
|
||||
"@mui/material": "^9.0.1",
|
||||
"@tanstack/react-query": "^5.100.14",
|
||||
"@tanstack/react-virtual": "^3.13.25",
|
||||
"@tauri-apps/api": "2.11.1",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
|
||||
@@ -74,6 +73,7 @@
|
||||
"react-markdown": "10.1.0",
|
||||
"react-router": "^8.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"swr": "^2.4.2",
|
||||
"tauri-plugin-mihomo-api": "github:clash-verge-rev/tauri-plugin-mihomo",
|
||||
"types-pac": "^1.0.3",
|
||||
"validator": "^13.15.35"
|
||||
|
||||
Generated
+14
-18
@@ -35,9 +35,6 @@ importers:
|
||||
'@mui/material':
|
||||
specifier: ^9.0.1
|
||||
version: 9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.100.14
|
||||
version: 5.100.14(react@19.2.7)
|
||||
'@tanstack/react-virtual':
|
||||
specifier: ^3.13.25
|
||||
version: 3.13.25(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
@@ -128,6 +125,9 @@ importers:
|
||||
rehype-raw:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
swr:
|
||||
specifier: ^2.4.2
|
||||
version: 2.4.2(react@19.2.7)
|
||||
tauri-plugin-mihomo-api:
|
||||
specifier: github:clash-verge-rev/tauri-plugin-mihomo
|
||||
version: https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/ff75ee3edd61923e6c76a7f3cf3c3fbd0f8e22c0
|
||||
@@ -1475,14 +1475,6 @@ packages:
|
||||
peerDependencies:
|
||||
'@svgr/core': '*'
|
||||
|
||||
'@tanstack/query-core@5.100.14':
|
||||
resolution: {integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==}
|
||||
|
||||
'@tanstack/react-query@5.100.14':
|
||||
resolution: {integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-virtual@3.13.25':
|
||||
resolution: {integrity: sha512-bmNoqMu6gcAW9JGrKVB0Q1tN1i5RONZF8r1fW0bbE4Oyf3DwEGnzzQJ2OW+Ozg1P4s8PyugkHg2ULZoFQN+cqw==}
|
||||
peerDependencies:
|
||||
@@ -3349,6 +3341,11 @@ packages:
|
||||
svg-parser@2.0.4:
|
||||
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
|
||||
|
||||
swr@2.4.2:
|
||||
resolution: {integrity: sha512-ej644Y2bvkIajfR32KGeSSdBXQW+ScjGjkybZgSE7kFpk9eGnV44XY9FJylXi+W75pavSX1PVNB57W5EbhGIYw==}
|
||||
peerDependencies:
|
||||
react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
systemjs@6.15.1:
|
||||
resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==}
|
||||
|
||||
@@ -4992,13 +4989,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/query-core@5.100.14': {}
|
||||
|
||||
'@tanstack/react-query@5.100.14(react@19.2.7)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.100.14
|
||||
react: 19.2.7
|
||||
|
||||
'@tanstack/react-virtual@3.13.25(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
|
||||
dependencies:
|
||||
'@tanstack/virtual-core': 3.15.0
|
||||
@@ -7032,6 +7022,12 @@ snapshots:
|
||||
|
||||
svg-parser@2.0.4: {}
|
||||
|
||||
swr@2.4.2(react@19.2.7):
|
||||
dependencies:
|
||||
dequal: 2.0.3
|
||||
react: 19.2.7
|
||||
use-sync-external-store: 1.6.0(react@19.2.7)
|
||||
|
||||
systemjs@6.15.1: {}
|
||||
|
||||
tar@7.5.15:
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
VisibilityOutlined,
|
||||
} from '@mui/icons-material'
|
||||
import { Box, Button, IconButton, Skeleton, Typography } from '@mui/material'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { useEffect } from 'foxact/use-abortable-effect'
|
||||
import { useIntersection } from 'foxact/use-intersection'
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { getIpInfo } from '@/services/api'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
|
||||
import { EnhancedCard } from './enhanced-card'
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { defaultRangeExtractor, useVirtualizer } from '@tanstack/react-virtual'
|
||||
import { useLockFn } from 'ahooks'
|
||||
import {
|
||||
@@ -34,6 +33,7 @@ import { useVerge } from '@/hooks/use-verge'
|
||||
import { useProxiesData } from '@/providers/app-data-context'
|
||||
import { calcuProxies, updateProxyChainConfigInRuntime } from '@/services/cmds'
|
||||
import delayManager from '@/services/delay'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { debugLog } from '@/utils/debug'
|
||||
|
||||
import { ScrollTopButton } from '../layout/scroll-top-button'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useLockFn } from 'ahooks'
|
||||
import { getVersion } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
getRuntimeConfig,
|
||||
patchClashConfig,
|
||||
} from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
|
||||
type MutateClashUpdater =
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { downloadIconCache } from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
|
||||
export interface UseIconCacheOptions {
|
||||
icon?: string | null
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import dayjs from 'dayjs'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { MihomoWebSocket, type LogLevel } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import { getClashLogs } from '@/services/cmds'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
|
||||
import { useClashLog } from './use-clash-log'
|
||||
import { useMihomoWsSubscription } from './use-mihomo-ws-subscription'
|
||||
@@ -48,7 +48,6 @@ const appendLogs = (
|
||||
}
|
||||
|
||||
export const useLogData = () => {
|
||||
const queryClient = useQueryClient()
|
||||
const [clashLog] = useClashLog()
|
||||
const enableLog = clashLog.enable
|
||||
const logLevel = clashLog.logLevel.toUpperCase() as LogLevel
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useLocalStorage } from 'foxact/use-local-storage'
|
||||
import { type MutableRefObject, useCallback, useEffect, useRef } from 'react'
|
||||
import { type Message, type MihomoWebSocket } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import { queryClient, useQuery } from '@/services/query-client'
|
||||
|
||||
export const RECONNECT_DELAY_MS = 1000
|
||||
|
||||
interface SharedSubscriptionOwner {
|
||||
@@ -195,8 +196,6 @@ export const useMihomoWsSubscription = <T>(
|
||||
const responseCacheKey =
|
||||
subscriptionCacheKey ?? lastSubscriptionCacheKeyRef.current
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const wsRef = useRef<MihomoWebSocket | null>(null)
|
||||
|
||||
const resolveNextData = useCallback(
|
||||
@@ -211,7 +210,7 @@ export const useMihomoWsSubscription = <T>(
|
||||
}
|
||||
return data ?? fallbackData
|
||||
},
|
||||
[queryClient, fallbackData],
|
||||
[fallbackData],
|
||||
)
|
||||
|
||||
const response = useQuery<T>({
|
||||
@@ -355,7 +354,7 @@ export const useMihomoWsSubscription = <T>(
|
||||
queryClient.removeQueries({ queryKey: [subscriptionCacheKey] })
|
||||
}
|
||||
setDate(Date.now())
|
||||
}, [queryClient, subscriptionCacheKey, setDate])
|
||||
}, [subscriptionCacheKey, setDate])
|
||||
|
||||
return { response, refresh, subscriptionCacheKey: responseCacheKey, wsRef }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { getNetworkInterfacesInfo } from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
|
||||
export const useNetworkInterfaces = () => {
|
||||
const {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { selectNodeForGroup } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import {
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
patchProfile,
|
||||
patchProfilesConfig,
|
||||
} from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
import { debugLog } from '@/utils/debug'
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useRef } from 'react'
|
||||
import { closeAllConnections } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { useClashConfigData, useSystemData } from '@/providers/app-data-context'
|
||||
import { getAutotemProxy } from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
|
||||
// 系统代理状态检测统一逻辑
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { getRunningMode, isAdmin, isServiceAvailable } from '@/services/cmds'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
|
||||
import { useVerge } from './use-verge'
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
import { checkUpdateSafe } from '@/services/update'
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { getVergeConfig, patchVergeConfig } from '@/services/cmds'
|
||||
import { getPreloadConfig, setPreloadConfig } from '@/services/preload'
|
||||
import { queryClient, useQuery } from '@/services/query-client'
|
||||
|
||||
export const useVerge = () => {
|
||||
const qc = useQueryClient()
|
||||
const initialVergeConfig = getPreloadConfig()
|
||||
|
||||
const { data: verge, refetch } = useQuery({
|
||||
@@ -31,11 +30,11 @@ export const useVerge = () => {
|
||||
return
|
||||
}
|
||||
if (typeof updaterOrData === 'function') {
|
||||
const prev = qc.getQueryData<IVergeConfig>(['getVergeConfig'])
|
||||
const prev = queryClient.getQueryData<IVergeConfig>(['getVergeConfig'])
|
||||
const next = updaterOrData(prev)
|
||||
qc.setQueryData(['getVergeConfig'], next)
|
||||
queryClient.setQueryData(['getVergeConfig'], next)
|
||||
} else {
|
||||
qc.setQueryData(['getVergeConfig'], updaterOrData)
|
||||
queryClient.setQueryData(['getVergeConfig'], updaterOrData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
import './assets/styles/index.scss'
|
||||
|
||||
import { ResizeObserver } from '@juggle/resize-observer'
|
||||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { ComposeContextProvider } from 'foxact/compose-context-provider'
|
||||
import React from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { RouterProvider } from 'react-router'
|
||||
import { SWRConfig } from 'swr'
|
||||
import { MihomoWebSocket } from 'tauri-plugin-mihomo-api'
|
||||
|
||||
import { BaseErrorBoundary } from './components/base'
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
resolveThemeMode,
|
||||
getPreloadConfig,
|
||||
} from './services/preload'
|
||||
import { queryClient } from './services/query-client'
|
||||
import { queryClientConfig } from './services/query-client'
|
||||
import {
|
||||
LoadingCacheProvider,
|
||||
ThemeModeProvider,
|
||||
@@ -51,13 +51,13 @@ const initializeApp = (initialThemeMode: 'light' | 'dark') => {
|
||||
<React.StrictMode>
|
||||
<ComposeContextProvider contexts={contexts}>
|
||||
<BaseErrorBoundary>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<SWRConfig value={queryClientConfig}>
|
||||
<WindowProvider>
|
||||
<AppDataProvider>
|
||||
<RouterProvider router={router} />
|
||||
</AppDataProvider>
|
||||
</WindowProvider>
|
||||
</QueryClientProvider>
|
||||
</SWRConfig>
|
||||
</BaseErrorBoundary>
|
||||
</ComposeContextProvider>
|
||||
</React.StrictMode>,
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
TextSnippetOutlined,
|
||||
} from '@mui/icons-material'
|
||||
import { Box, Button, Divider, Grid, IconButton, Stack } from '@mui/material'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { TauriEvent } from '@tauri-apps/api/event'
|
||||
import { readText } from '@tauri-apps/plugin-clipboard-manager'
|
||||
import { readTextFile } from '@tauri-apps/plugin-fs'
|
||||
@@ -65,6 +64,7 @@ import {
|
||||
updateProfile,
|
||||
} from '@/services/cmds'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
import {
|
||||
useLoadingCache,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||
import {
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
getRunningMode,
|
||||
getSystemProxy,
|
||||
} from '@/services/cmds'
|
||||
import { useQuery } from '@/services/query-client'
|
||||
import { queryClient } from '@/services/query-client'
|
||||
|
||||
import {
|
||||
|
||||
+174
-10
@@ -1,12 +1,176 @@
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
import { unstable_serialize } from 'swr'
|
||||
import useSWR, {
|
||||
type SWRConfiguration,
|
||||
type SWRResponse,
|
||||
mutate as swrMutate,
|
||||
} from 'swr'
|
||||
|
||||
export const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 2000,
|
||||
retry: 3,
|
||||
retryDelay: 5000,
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
type QueryKey = string | readonly unknown[]
|
||||
|
||||
type QueryOptions<T> = {
|
||||
queryKey: QueryKey
|
||||
queryFn: () => Promise<T> | T
|
||||
enabled?: boolean
|
||||
initialData?: T | (() => T | undefined)
|
||||
placeholderData?: T | (() => T | undefined)
|
||||
staleTime?: number
|
||||
gcTime?: number
|
||||
retry?: number | false
|
||||
retryDelay?: number | ((attempt: number) => number)
|
||||
refetchInterval?: number | false
|
||||
refetchIntervalInBackground?: boolean
|
||||
refetchOnWindowFocus?: boolean
|
||||
refetchOnReconnect?: boolean
|
||||
}
|
||||
|
||||
type QueryResult<T> = Omit<SWRResponse<T>, 'mutate'> & {
|
||||
isFetching: boolean
|
||||
isPending: boolean
|
||||
refetch: () => Promise<{ data: T | undefined }>
|
||||
mutate: SWRResponse<T>['mutate']
|
||||
}
|
||||
|
||||
type QueryFilters = {
|
||||
queryKey: QueryKey
|
||||
}
|
||||
|
||||
const keyToSWRKey = (queryKey: QueryKey) => {
|
||||
return Array.isArray(queryKey) ? [...queryKey] : queryKey
|
||||
}
|
||||
|
||||
const serializeQueryKey = (queryKey: QueryKey) => {
|
||||
return unstable_serialize(keyToSWRKey(queryKey))
|
||||
}
|
||||
|
||||
const resolveFallbackData = <T>(
|
||||
initialData: QueryOptions<T>['initialData'],
|
||||
placeholderData: QueryOptions<T>['placeholderData'],
|
||||
) => {
|
||||
const data = initialData ?? placeholderData
|
||||
return typeof data === 'function' ? (data as () => T | undefined)() : data
|
||||
}
|
||||
|
||||
const resolveRetryInterval = (
|
||||
retryDelay: QueryOptions<unknown>['retryDelay'],
|
||||
) => {
|
||||
if (typeof retryDelay !== 'function') return retryDelay
|
||||
return retryDelay(0)
|
||||
}
|
||||
|
||||
export const queryCache = new Map<string, unknown>()
|
||||
|
||||
export const queryClientConfig: SWRConfiguration = {
|
||||
dedupingInterval: 2000,
|
||||
errorRetryCount: 3,
|
||||
errorRetryInterval: 5000,
|
||||
revalidateOnFocus: false,
|
||||
}
|
||||
|
||||
export const queryClient = {
|
||||
getQueryData<T>(queryKey: QueryKey): T | undefined {
|
||||
return queryCache.get(serializeQueryKey(queryKey)) as T | undefined
|
||||
},
|
||||
})
|
||||
|
||||
setQueryData<T>(
|
||||
queryKey: QueryKey,
|
||||
updaterOrData: T | undefined | ((current: T | undefined) => T | undefined),
|
||||
) {
|
||||
const current = this.getQueryData<T>(queryKey)
|
||||
const next =
|
||||
typeof updaterOrData === 'function'
|
||||
? (updaterOrData as (current: T | undefined) => T | undefined)(current)
|
||||
: updaterOrData
|
||||
|
||||
if (next === undefined) {
|
||||
queryCache.delete(serializeQueryKey(queryKey))
|
||||
} else {
|
||||
queryCache.set(serializeQueryKey(queryKey), next)
|
||||
}
|
||||
|
||||
void swrMutate(keyToSWRKey(queryKey), next, {
|
||||
populateCache: true,
|
||||
revalidate: false,
|
||||
})
|
||||
return next
|
||||
},
|
||||
|
||||
invalidateQueries({ queryKey }: QueryFilters) {
|
||||
return swrMutate(keyToSWRKey(queryKey))
|
||||
},
|
||||
|
||||
removeQueries({ queryKey }: QueryFilters) {
|
||||
queryCache.delete(serializeQueryKey(queryKey))
|
||||
return swrMutate(keyToSWRKey(queryKey), undefined, {
|
||||
populateCache: true,
|
||||
revalidate: false,
|
||||
})
|
||||
},
|
||||
|
||||
async fetchQuery<T>({
|
||||
queryKey,
|
||||
queryFn,
|
||||
}: {
|
||||
queryKey: QueryKey
|
||||
queryFn: () => Promise<T> | T
|
||||
}) {
|
||||
const data = await queryFn()
|
||||
this.setQueryData(queryKey, data)
|
||||
return data
|
||||
},
|
||||
}
|
||||
|
||||
export const invalidateQueries = (queryKeys: readonly QueryKey[]) =>
|
||||
Promise.all(
|
||||
queryKeys.map((queryKey) => queryClient.invalidateQueries({ queryKey })),
|
||||
)
|
||||
|
||||
export function useQuery<T>(options: QueryOptions<T>): QueryResult<T> {
|
||||
const {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled = true,
|
||||
initialData,
|
||||
placeholderData,
|
||||
retry,
|
||||
retryDelay,
|
||||
refetchInterval,
|
||||
refetchIntervalInBackground,
|
||||
refetchOnWindowFocus,
|
||||
refetchOnReconnect,
|
||||
staleTime,
|
||||
} = options
|
||||
|
||||
const fallbackData = resolveFallbackData(initialData, placeholderData)
|
||||
const serializedKey = serializeQueryKey(queryKey)
|
||||
if (enabled && fallbackData !== undefined && !queryCache.has(serializedKey)) {
|
||||
queryCache.set(serializedKey, fallbackData)
|
||||
}
|
||||
|
||||
const swr = useSWR<T>(enabled ? keyToSWRKey(queryKey) : null, queryFn, {
|
||||
dedupingInterval: staleTime,
|
||||
errorRetryCount: retry === false ? 0 : retry,
|
||||
errorRetryInterval: resolveRetryInterval(retryDelay),
|
||||
fallbackData,
|
||||
keepPreviousData: placeholderData !== undefined,
|
||||
revalidateOnFocus: refetchOnWindowFocus,
|
||||
revalidateOnReconnect: refetchOnReconnect,
|
||||
refreshInterval: refetchInterval || 0,
|
||||
refreshWhenHidden: refetchIntervalInBackground ?? false,
|
||||
onSuccess: (data) => {
|
||||
queryCache.set(serializedKey, data)
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
...swr,
|
||||
isFetching: swr.isValidating,
|
||||
isPending: swr.isLoading,
|
||||
refetch: async () => {
|
||||
const data = await swr.mutate()
|
||||
if (data !== undefined) {
|
||||
queryCache.set(serializedKey, data)
|
||||
}
|
||||
return { data }
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user