Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixes #1968

Merged
merged 4 commits into from May 15, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion _internal/utils/helper.ts
@@ -1,5 +1,7 @@
import { SWRGlobalState } from './global-state'
import { Key, Cache, State, GlobalState } from '../types'

const EMPTY_CACHE = {}
export const noop = () => {}

// Using noop() as the undefined value as undefined can possibly be replaced
Expand All @@ -23,7 +25,6 @@ export const isDocumentDefined = typeof document != STR_UNDEFINED
export const hasRequestAnimationFrame = () =>
isWindowDefined && typeof window['requestAnimationFrame'] != STR_UNDEFINED

const EMPTY_CACHE = {}
export const createCacheHelper = <Data = any, T = State<Data, any>>(
cache: Cache,
key: Key
Expand Down
2 changes: 1 addition & 1 deletion _internal/utils/resolve-args.ts
Expand Up @@ -19,7 +19,7 @@ export const withArgs = <SWRType>(hook: any) => {
let next = hook
const { use } = config
if (use) {
for (let i = use.length; i-- > 0; ) {
for (let i = use.length; i--; ) {
next = use[i](next)
}
}
Expand Down
35 changes: 18 additions & 17 deletions infinite/index.ts
Expand Up @@ -30,6 +30,7 @@ import type {
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'

const INFINITE_PREFIX = '$inf$'
const EMPTY_PROMISE = Promise.resolve(UNDEFINED)
shuding marked this conversation as resolved.
Show resolved Hide resolved

const getFirstPageKey = (getKey: SWRInfiniteKeyLoader) => {
return serialize(getKey ? getKey(0, null) : null)[0]
Expand Down Expand Up @@ -192,27 +193,21 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
}, [swr.data])

const mutate = useCallback(
(
...args:
| []
| [undefined | Data[] | Promise<Data[]> | MutatorCallback<Data[]>]
| [
undefined | Data[] | Promise<Data[]> | MutatorCallback<Data[]>,
undefined | boolean | MutatorOptions<Data>
]
) => {
const data = args[0]

// eslint-disable-next-line func-names
function (
data?: undefined | Data[] | Promise<Data[]> | MutatorCallback<Data[]>,
opts?: undefined | boolean | MutatorOptions<Data[]>
) {
// When passing as a boolean, it's explicitly used to disable/enable
// revalidation.
const options =
typeof args[1] === 'boolean' ? { revalidate: args[1] } : args[1] || {}
typeof opts === 'boolean' ? { revalidate: opts } : opts || {}

// Default to true.
const shouldRevalidate = options.revalidate !== false

// It is possible that the key is still falsy.
if (!infiniteKey) return
if (!infiniteKey) return EMPTY_PROMISE

if (shouldRevalidate) {
if (!isUndefined(data)) {
Expand All @@ -225,7 +220,13 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
}
}

return args.length ? swr.mutate(data, shouldRevalidate) : swr.mutate()
// We are using `arguments` here because there's no other way around to
// tell if an argument is missing or `undefined`. It will be compiled to
// `arguments` anyways.
// @ts-ignore
return arguments.length
shuding marked this conversation as resolved.
Show resolved Hide resolved
? swr.mutate(data, shouldRevalidate)
: swr.mutate()
},
// swr.mutate is always the same reference
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -259,15 +260,15 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
const setSize = useCallback(
(arg: number | ((size: number) => number)) => {
// It is possible that the key is still falsy.
if (!infiniteKey) return
if (!infiniteKey) return EMPTY_PROMISE

let size
if (isFunction(arg)) {
size = arg(resolvePageSize())
} else if (typeof arg == 'number') {
size = arg
}
if (typeof size != 'number') return
if (typeof size != 'number') return EMPTY_PROMISE

set({ $len: size })
lastPageSizeRef.current = size
Expand Down Expand Up @@ -296,7 +297,7 @@ export const infinite = (<Data, Error>(useSWRNext: SWRHook) =>
get isLoading() {
return swr.isLoading
}
} as SWRInfiniteResponse<Data, Error>
}
}) as unknown as Middleware

export default withMiddleware(useSWR, infinite) as SWRInfiniteHook
Expand Down
15 changes: 15 additions & 0 deletions test/use-swr-infinite.test.tsx
Expand Up @@ -925,6 +925,21 @@ describe('useSWRInfinite', () => {
await screen.findByText('size: 3')
})

it('setSize should return a promise', async () => {
let _setSize
function Comp() {
const { setSize } = useSWRInfinite(
() => null,
() => createResponse('')
)

_setSize = setSize
return null
}
renderWithConfig(<Comp />)
expect(_setSize()).toBeInstanceOf(Promise)
})

// https://github.com/vercel/swr/issues/908
//TODO: This test trigger act warning
it('should revalidate first page after mutating', async () => {
Expand Down