Skip to content

Commit abe7409

Browse files
fix: enabled effect and drop unecessary refs (#213)
1 parent ad5d479 commit abe7409

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

packages/use-dataloader/src/__tests__/useDataLoader.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ describe('useDataLoader', () => {
256256
expect(result.current.isPolling).toBe(true)
257257
expect(result.current.isLoading).toBe(true)
258258
expect(result.current.isSuccess).toBe(false)
259-
expect(method2).toBeCalledTimes(1)
260259
await waitForNextUpdate()
260+
expect(method2).toBeCalledTimes(1)
261261
expect(result.current.isPolling).toBe(true)
262262
expect(result.current.isLoading).toBe(false)
263263
expect(result.current.isSuccess).toBe(true)

packages/use-dataloader/src/useDataLoader.js

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { useEffect, useLayoutEffect, useMemo, useReducer, useRef } from 'react'
1+
import {
2+
useCallback,
3+
useEffect,
4+
useLayoutEffect,
5+
useMemo,
6+
useReducer,
7+
useRef,
8+
} from 'react'
29
import { useDataLoaderContext } from './DataLoaderProvider'
310
import { ActionEnum, StatusEnum } from './constants'
411
import reducer from './reducer'
@@ -75,10 +82,6 @@ const useDataLoader = (
7582
}, [cacheKeyPrefix, fetchKey])
7683

7784
const previousDataRef = useRef()
78-
const isMountedRef = useRef(enabled)
79-
const methodRef = useRef(method)
80-
const onSuccessRef = useRef(onSuccess)
81-
const onErrorRef = useRef(onError)
8285

8386
const isLoading = useMemo(() => status === StatusEnum.LOADING, [status])
8487
const isIdle = useMemo(() => status === StatusEnum.IDLE, [status])
@@ -90,53 +93,62 @@ const useDataLoader = (
9093
[isSuccess, isLoading, enabled, pollingInterval],
9194
)
9295

93-
const handleRequest = useRef(async cacheKey => {
94-
try {
95-
dispatch(Actions.createOnLoading())
96-
const result = await methodRef.current?.()
96+
const handleRequest = useCallback(
97+
async cacheKey => {
98+
try {
99+
dispatch(Actions.createOnLoading())
100+
const result = await method()
97101

98-
if (keepPreviousData) {
99-
previousDataRef.current = getCachedData(cacheKey)
100-
}
101-
if (result !== undefined && result !== null && cacheKey)
102-
addCachedData(cacheKey, result)
102+
if (keepPreviousData) {
103+
previousDataRef.current = getCachedData(cacheKey)
104+
}
105+
if (result !== undefined && result !== null && cacheKey)
106+
addCachedData(cacheKey, result)
103107

104-
dispatch(Actions.createOnSuccess())
108+
dispatch(Actions.createOnSuccess())
105109

106-
await onSuccessRef.current?.(result)
107-
} catch (err) {
108-
dispatch(Actions.createOnError(err))
109-
await onErrorRef.current?.(err)
110-
}
111-
})
110+
await onSuccess?.(result)
111+
} catch (err) {
112+
dispatch(Actions.createOnError(err))
113+
await onError?.(err)
114+
}
115+
},
116+
[
117+
addCachedData,
118+
getCachedData,
119+
keepPreviousData,
120+
method,
121+
onError,
122+
onSuccess,
123+
],
124+
)
125+
126+
const handleRequestRef = useRef(handleRequest)
112127

113128
useEffect(() => {
114129
let handler
115-
if (isMountedRef.current) {
130+
if (enabled) {
116131
if (isIdle) {
117-
handleRequest.current(key)
132+
handleRequestRef.current(key)
118133
}
119-
if (pollingInterval && isSuccess) {
120-
handler = setTimeout(() => handleRequest.current(key), pollingInterval)
134+
if (pollingInterval && (isSuccess || isError)) {
135+
handler = setTimeout(
136+
() => handleRequestRef.current(key),
137+
pollingInterval,
138+
)
121139
}
122140
}
123141

124142
return () => {
125143
if (handler) clearTimeout(handler)
126144
}
127-
// Why can't put empty array for componentDidMount, componentWillUnmount ??? No array act like componentDidMount and componentDidUpdate
128-
}, [key, pollingInterval, isIdle, isSuccess])
129-
130-
useLayoutEffect(() => {
131-
methodRef.current = method
132-
}, [method])
145+
}, [key, pollingInterval, isIdle, isSuccess, isError, enabled])
133146

134147
useLayoutEffect(() => {
135-
isMountedRef.current = enabled
136148
dispatch(Actions.createReset())
137149
if (key && typeof key === 'string') {
138150
addReloadRef.current?.(key, reloadArgs =>
139-
handleRequest.current(key, reloadArgs),
151+
handleRequestRef.current(key, reloadArgs),
140152
)
141153
}
142154

@@ -152,6 +164,10 @@ const useDataLoader = (
152164
addReloadRef.current = addReload
153165
}, [clearReload, addReload])
154166

167+
useLayoutEffect(() => {
168+
handleRequestRef.current = handleRequest
169+
}, [handleRequest])
170+
155171
return {
156172
data: getCachedData(key) || initialData,
157173
error,
@@ -161,7 +177,7 @@ const useDataLoader = (
161177
isPolling,
162178
isSuccess,
163179
previousData: previousDataRef.current,
164-
reload: args => handleRequest.current(key, args),
180+
reload: args => handleRequestRef.current(key, args),
165181
}
166182
}
167183

0 commit comments

Comments
 (0)