Skip to content

Commit

Permalink
fix: only make data and error update as a non-blocking transition
Browse files Browse the repository at this point in the history
  • Loading branch information
promer94 committed Jun 24, 2023
1 parent 3c89b6e commit cc02dbc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 30 deletions.
5 changes: 3 additions & 2 deletions mutation/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useRef } from 'react'
import useSWR, { useSWRConfig } from 'swr'
import type { Middleware, Key } from 'swr/_internal'
import { useStateWithDeps, startTransition } from './state'
import { useStateWithDeps, useTransition } from './state'
import {
serialize,
withMiddleware,
Expand All @@ -23,6 +23,7 @@ const mutation = (<Data, Error>() =>
fetcher: MutationFetcher<Data>,
config: SWRMutationConfiguration<Data, Error> = {}
) => {
const [isPending, startTransition] = useTransition()
const { mutate } = useSWRConfig()
const keyRef = useRef(key)
const fetcherRef = useRef(fetcher)
Expand Down Expand Up @@ -127,7 +128,7 @@ const mutation = (<Data, Error>() =>
},
get isMutating() {
stateDependencies.isMutating = true
return currentState.isMutating
return isPending || currentState.isMutating
}
}
}) as unknown as Middleware
Expand Down
54 changes: 27 additions & 27 deletions mutation/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import type { MutableRefObject } from 'react'
import React, { useRef, useCallback, useState } from 'react'
import { useIsomorphicLayoutEffect, IS_REACT_LEGACY } from 'swr/_internal'

export const startTransition = IS_REACT_LEGACY
? (fn: (...args: any[]) => any) => {
fn()
}
: React.startTransition
const startTrainstion: React.TransitionStartFunction = callback => {
callback()
}
export const useTransition: () => [
isPending: boolean,
startTransition: React.TransitionStartFunction
] = IS_REACT_LEGACY ? () => [false, startTrainstion] : React.useTransition

/**
* An implementation of state with dependency-tracking.
*/
Expand All @@ -17,7 +20,7 @@ export const useStateWithDeps = <S = any>(
Record<keyof S, boolean>,
(payload: Partial<S>) => void
] => {
const rerender = useState<Record<string, unknown>>({})[1]
const [, rerender] = useState<Record<string, unknown>>({})
const unmountedRef = useRef(false)
const stateRef = useRef(state)

Expand Down Expand Up @@ -48,33 +51,30 @@ export const useStateWithDeps = <S = any>(
* })
* ```
*/
const setState = useCallback(
(payload: Partial<S>) => {
let shouldRerender = false
const setState = useCallback((payload: Partial<S>) => {
let shouldRerender = false

const currentState = stateRef.current
for (const _ in payload) {
const k = _ as keyof S
const currentState = stateRef.current
for (const _ in payload) {
const k = _ as keyof S

// If the property has changed, update the state and mark rerender as
// needed.
if (currentState[k] !== payload[k]) {
currentState[k] = payload[k]
// If the property has changed, update the state and mark rerender as
// needed.
if (currentState[k] !== payload[k]) {
currentState[k] = payload[k]

// If the property is accessed by the component, a rerender should be
// triggered.
if (stateDependenciesRef.current[k]) {
shouldRerender = true
}
// If the property is accessed by the component, a rerender should be
// triggered.
if (stateDependenciesRef.current[k]) {
shouldRerender = true
}
}
}

if (shouldRerender && !unmountedRef.current) {
rerender({})
}
},
[rerender]
)
if (shouldRerender && !unmountedRef.current) {
rerender({})
}
}, [])

useIsomorphicLayoutEffect(() => {
unmountedRef.current = false
Expand Down
2 changes: 1 addition & 1 deletion test/use-swr-remote-mutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ describe('useSWR - remote mutation', () => {
await act(() => sleep(20))

// Shouldn't have intermediate states
expect(logger).toEqual([undefined, 2])
expect(logger).toEqual([undefined, 2, 2])
})

it('should error if no mutator is given', async () => {
Expand Down

0 comments on commit cc02dbc

Please sign in to comment.