Skip to content

Commit de9db65

Browse files
committed
move argument resolving out
1 parent 7bb2ade commit de9db65

File tree

3 files changed

+56
-50
lines changed

3 files changed

+56
-50
lines changed

src/resolve-args.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useContext } from 'react'
2+
3+
import defaultConfig from './config'
4+
import SWRConfigContext from './config-context'
5+
6+
import { Fetcher } from './types'
7+
8+
// Resolve arguments for SWR hooks.
9+
// This function itself is a hook because it uses `useContext` inside.
10+
export default function useArgs<KeyType, ConfigType, Data>(
11+
args:
12+
| readonly [KeyType]
13+
| readonly [KeyType, Fetcher<Data> | null]
14+
| readonly [KeyType, ConfigType | undefined]
15+
| readonly [KeyType, Fetcher<Data> | null, ConfigType | undefined]
16+
): [KeyType, (typeof defaultConfig) & ConfigType, Fetcher<Data> | null] {
17+
const config = Object.assign(
18+
{},
19+
defaultConfig,
20+
useContext(SWRConfigContext),
21+
args.length > 2
22+
? args[2]
23+
: args.length === 2 && typeof args[1] === 'object'
24+
? args[1]
25+
: {}
26+
) as (typeof defaultConfig) & ConfigType
27+
28+
// In TypeScript `args.length > 2` is not same as `args.lenth === 3`.
29+
// We do a safe type assertion here.
30+
const fn = (args.length > 2
31+
? args[1]
32+
: args.length === 2 && typeof args[1] === 'function'
33+
? args[1]
34+
: // Pass fn as null will disable revalidate
35+
// https://paco.sh/blog/shared-hook-state-with-swr
36+
args[1] === null
37+
? args[1]
38+
: config.fetcher) as Fetcher<Data> | null
39+
40+
return [args[0], config, fn]
41+
}

src/use-swr-infinite.ts

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// TODO: use @ts-expect-error
2-
import { useContext, useRef, useState, useCallback } from 'react'
2+
import { useRef, useState, useCallback } from 'react'
33

4-
import defaultConfig, { cache } from './config'
4+
import { cache } from './config'
55
import { useIsomorphicLayoutEffect } from './env'
6-
import SWRConfigContext from './config-context'
6+
import useArgs from './resolve-args'
77
import useSWR from './use-swr'
88

99
import {
@@ -17,37 +17,22 @@ import {
1717
function useSWRInfinite<Data = any, Error = any>(
1818
...args:
1919
| readonly [KeyLoader<Data>]
20-
| readonly [KeyLoader<Data>, Fetcher<Data>]
20+
| readonly [KeyLoader<Data>, Fetcher<Data> | null]
2121
| readonly [
2222
KeyLoader<Data>,
2323
SWRInfiniteConfiguration<Data, Error> | undefined
2424
]
2525
| readonly [
2626
KeyLoader<Data>,
27-
Fetcher<Data>,
27+
Fetcher<Data> | null,
2828
SWRInfiniteConfiguration<Data, Error> | undefined
2929
]
3030
): SWRInfiniteResponse<Data, Error> {
31-
const getKey = args[0]
32-
33-
const config = Object.assign(
34-
{},
35-
defaultConfig,
36-
useContext(SWRConfigContext),
37-
args.length > 2
38-
? args[2]
39-
: args.length === 2 && typeof args[1] === 'object'
40-
? args[1]
41-
: {}
42-
)
43-
// in typescript args.length > 2 is not same as args.lenth === 3
44-
// we do a safe type assertion here
45-
// args.length === 3
46-
const fn = (args.length > 2
47-
? args[1]
48-
: args.length === 2 && typeof args[1] === 'function'
49-
? args[1]
50-
: config.fetcher) as Fetcher<Data>
31+
const [getKey, config, fn] = useArgs<
32+
KeyLoader<Data>,
33+
SWRInfiniteConfiguration<Data, Error>,
34+
Data
35+
>(args)
5136

5237
const {
5338
initialSize = 1,
@@ -145,7 +130,7 @@ function useSWRInfinite<Data = any, Error = any>(
145130
typeof dataRef.current !== 'undefined') ||
146131
(originalData && !config.compare(originalData[i], pageData))
147132

148-
if (shouldFetchPage) {
133+
if (fn && shouldFetchPage) {
149134
if (pageArgs !== null) {
150135
pageData = await fn(...pageArgs)
151136
} else {

src/use-swr.ts

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// TODO: use @ts-expect-error
2-
import { useCallback, useContext, useRef, useDebugValue } from 'react'
2+
import { useCallback, useRef, useDebugValue } from 'react'
33

44
import defaultConfig, { cache } from './config'
55
import { IS_SERVER, rAF, useIsomorphicLayoutEffect } from './env'
66
import SWRConfigContext from './config-context'
77
import useStateWithDeps from './state'
8+
import useArgs from './resolve-args'
89

910
import {
1011
State,
@@ -223,31 +224,10 @@ function useSWR<Data = any, Error = any>(
223224
SWRConfiguration<Data, Error> | undefined
224225
]
225226
): SWRResponse<Data, Error> {
226-
// Resolve arguments
227-
const _key = args[0]
228-
const config = Object.assign(
229-
{},
230-
defaultConfig,
231-
useContext(SWRConfigContext),
232-
args.length > 2
233-
? args[2]
234-
: args.length === 2 && typeof args[1] === 'object'
235-
? args[1]
236-
: {}
227+
const [_key, config, fn] = useArgs<Key, SWRConfiguration<Data, Error>, Data>(
228+
args
237229
)
238230

239-
// In TypeScript `args.length > 2` is not same as `args.lenth === 3`.
240-
// We do a safe type assertion here.
241-
const fn = (args.length > 2
242-
? args[1]
243-
: args.length === 2 && typeof args[1] === 'function'
244-
? args[1]
245-
: // Pass fn as null will disable revalidate
246-
// https://paco.sh/blog/shared-hook-state-with-swr
247-
args[1] === null
248-
? args[1]
249-
: config.fetcher) as Fetcher<Data> | null
250-
251231
// `key` is the identifier of the SWR `data` state.
252232
// `keyErr` and `keyValidating` are indentifiers of `error` and `isValidating`
253233
// which are derived from `key`.

0 commit comments

Comments
 (0)