Skip to content

Commit 5a569a1

Browse files
feat: add a new datalifetime on provider and fix useinfinitedataloader (#2548)
* fix: use infinite and add defaut lifetime * fix: add changeset
1 parent 7d6c6b8 commit 5a569a1

File tree

5 files changed

+101
-58
lines changed

5 files changed

+101
-58
lines changed

.changeset/all-mirrors-win.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@scaleway/use-dataloader": minor
3+
---
4+
5+
Fix: useInfiniteDataloader doesnt update on params change

.changeset/young-ants-rescue.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@scaleway/use-dataloader": minor
3+
---
4+
5+
Feat: Add a default lifetime on the provider

packages/use-dataloader/src/DataLoaderProvider.tsx

+8-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ type Requests = Record<string, DataLoader<unknown, unknown>>
1414

1515
type UseDataLoaderInitializerArgs<ResultType = unknown> = {
1616
method: () => PromiseType<ResultType>
17-
/**
18-
* Max time before data from previous success is considered as outdated (in millisecond)
19-
*/
20-
maxDataLifetime?: number
2117
enabled?: boolean
2218
}
2319

@@ -42,6 +38,7 @@ export type IDataLoaderContext = {
4238
) => DataLoader<ResultType, ErrorType>
4339
computeKey: (key: string) => string
4440
cacheKeyPrefix?: string
41+
defaultDatalifetime?: number
4542
onError?: (error: Error) => void | Promise<void>
4643
clearAllCachedData: () => void
4744
clearCachedData: (key: string) => void
@@ -63,13 +60,18 @@ type DataLoaderProviderProps = {
6360
cacheKeyPrefix?: string
6461
onError?: OnErrorFn
6562
maxConcurrentRequests?: number
63+
/**
64+
* Default request lifetime in milliseconds. It doesnt override values passed to hooks
65+
*/
66+
defaultDatalifetime?: number
6667
}
6768

6869
const DataLoaderProvider = ({
6970
children,
7071
cacheKeyPrefix,
7172
onError,
7273
maxConcurrentRequests = DEFAULT_MAX_CONCURRENT_REQUESTS,
74+
defaultDatalifetime,
7375
}: DataLoaderProviderProps): ReactElement => {
7476
const requestsRef = useRef<Requests>({})
7577

@@ -204,6 +206,7 @@ const DataLoaderProvider = ({
204206
reloadAll,
205207
reloadGroup,
206208
computeKey,
209+
defaultDatalifetime,
207210
}),
208211
[
209212
addRequest,
@@ -219,6 +222,7 @@ const DataLoaderProvider = ({
219222
reloadAll,
220223
reloadGroup,
221224
computeKey,
225+
defaultDatalifetime,
222226
],
223227
)
224228

packages/use-dataloader/src/useDataLoader.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ export const useDataLoader = <ResultType = unknown, ErrorType = Error>(
2323
dataLifetime,
2424
}: UseDataLoaderConfig<ResultType, ErrorType> = {},
2525
): UseDataLoaderResult<ResultType, ErrorType> => {
26-
const { getOrAddRequest, onError: onGlobalError } = useDataLoaderContext()
26+
const {
27+
getOrAddRequest,
28+
onError: onGlobalError,
29+
defaultDatalifetime,
30+
} = useDataLoaderContext()
31+
const computedDatalifetime = dataLifetime ?? defaultDatalifetime
2732
const methodRef = useRef(method)
2833
const onSuccessRef = useRef(onSuccess)
2934
const onErrorRef = useRef(onError ?? onGlobalError)
@@ -54,12 +59,12 @@ export const useDataLoader = <ResultType = unknown, ErrorType = Error>(
5459
!!(
5560
enabled &&
5661
(!request.dataUpdatedAt ||
57-
!dataLifetime ||
62+
!computedDatalifetime ||
5863
(request.dataUpdatedAt &&
59-
dataLifetime &&
60-
request.dataUpdatedAt + dataLifetime < Date.now()))
64+
computedDatalifetime &&
65+
request.dataUpdatedAt + computedDatalifetime < Date.now()))
6166
),
62-
[enabled, request.dataUpdatedAt, dataLifetime],
67+
[enabled, request.dataUpdatedAt, computedDatalifetime],
6368
)
6469

6570
const optimisticIsLoadingRef = useRef(needLoad)

packages/use-dataloader/src/useInfiniteDataLoader.ts

+73-49
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const useInfiniteDataLoader = <
3434
getOrAddRequest,
3535
computeKey,
3636
onError: onGlobalError,
37+
defaultDatalifetime,
3738
} = useDataLoaderContext()
3839
const {
3940
enabled = true,
@@ -44,24 +45,32 @@ export const useInfiniteDataLoader = <
4445
dataLifetime,
4546
getNextPage,
4647
} = config ?? {}
48+
const computedDatalifetime = dataLifetime ?? defaultDatalifetime
4749
const requestRefs = useRef<DataLoader<ResultType, ErrorType>[]>([])
4850
const [page, setPage] = useState(baseParams[pageParamKey])
4951
const nextPageRef = useRef(page)
50-
const getNextPageRef = useRef(getNextPage)
51-
const methodRef = useRef(() =>
52-
method(
53-
pageParamKey && page
54-
? ({ ...baseParams, [pageParamKey]: page } as ParamsType)
55-
: baseParams,
56-
),
52+
53+
const getNextPageFnRef = useRef(
54+
(...params: Parameters<NonNullable<typeof getNextPage>>) =>
55+
getNextPage ? getNextPage(...params) : undefined,
56+
)
57+
58+
const getParamsRef = useRef(() => ({
59+
...baseParams,
60+
[pageParamKey]: nextPageRef.current,
61+
}))
62+
63+
const getMethodRef = useRef(() => method(getParamsRef.current()))
64+
65+
const getOnSuccessRef = useRef(
66+
(...params: Parameters<NonNullable<typeof onSuccess>>) =>
67+
onSuccess?.(...params),
5768
)
58-
const paramsRef = useRef(
59-
pageParamKey && page
60-
? ({ ...baseParams, [pageParamKey]: page } as ParamsType)
61-
: baseParams,
69+
70+
const getOnErrorRef = useRef(
71+
(err: ErrorType) => onError?.(err) ?? onGlobalError?.(err),
6272
)
63-
const onSuccessRef = useRef(onSuccess)
64-
const onErrorRef = useRef(onError ?? onGlobalError)
73+
6574
const [, setCounter] = useState(0)
6675

6776
const forceRerender = useCallback(() => {
@@ -99,7 +108,7 @@ export const useInfiniteDataLoader = <
99108
if (!requestInRef) {
100109
const request = getOrAddRequest<ResultType, ErrorType>(currentQueryKey, {
101110
enabled,
102-
method: methodRef.current,
111+
method: getMethodRef.current,
103112
})
104113
requestRefs.current.push(request)
105114
request.addObserver(forceRerender)
@@ -117,12 +126,12 @@ export const useInfiniteDataLoader = <
117126
!!(
118127
enabled &&
119128
(!request.dataUpdatedAt ||
120-
!dataLifetime ||
129+
!computedDatalifetime ||
121130
(request.dataUpdatedAt &&
122-
dataLifetime &&
123-
request.dataUpdatedAt + dataLifetime < Date.now()))
131+
computedDatalifetime &&
132+
request.dataUpdatedAt + computedDatalifetime < Date.now()))
124133
),
125-
[enabled, request.dataUpdatedAt, dataLifetime],
134+
[enabled, request.dataUpdatedAt, computedDatalifetime],
126135
)
127136

128137
const optimisticIsLoadingRef = useRef(needLoad)
@@ -149,64 +158,79 @@ export const useInfiniteDataLoader = <
149158
const reload = useCallback(async () => {
150159
await Promise.all(
151160
requestRefs.current.map(req =>
152-
req.load(true).then(onSuccessRef.current).catch(onErrorRef.current),
161+
req
162+
.load(true)
163+
.then(getOnSuccessRef.current)
164+
.catch(getOnErrorRef.current),
153165
),
154166
)
155167
}, [])
156168

157-
useEffect(() => {
158-
request.method = () => method(paramsRef.current)
159-
}, [method, request])
160-
161-
useEffect(() => {
162-
onSuccessRef.current = onSuccess
163-
}, [onSuccess])
169+
const loadMore = useCallback(() => {
170+
const nextPage = nextPageRef.current
171+
if (nextPage) {
172+
setPage(() => nextPage)
173+
getParamsRef.current = () => ({
174+
...baseParams,
175+
[pageParamKey]: nextPage,
176+
})
177+
}
178+
}, [baseParams, pageParamKey])
164179

165180
useEffect(() => {
166-
onErrorRef.current = onError ?? onGlobalError
167-
}, [onError, onGlobalError])
181+
request.method = () => method(getParamsRef.current())
182+
}, [method, request])
168183

169184
useEffect(() => {
170185
if (keepPreviousData) {
171186
previousDataRef.current = request.data
172187
}
173188
}, [request.data, keepPreviousData])
174189

190+
// Reset page when baseParams or pageParamKey change
175191
useEffect(() => {
176-
getNextPageRef.current = getNextPage
177-
}, [getNextPage])
178-
179-
useEffect(() => {
180-
paramsRef.current =
181-
pageParamKey && page
182-
? ({ ...baseParams, [pageParamKey]: page } as ParamsType)
183-
: baseParams
184-
}, [baseParams, pageParamKey, page])
192+
setPage(() => baseParams[pageParamKey])
193+
nextPageRef.current = baseParams[pageParamKey]
194+
getParamsRef.current = () => ({
195+
...baseParams,
196+
[pageParamKey]: nextPageRef.current,
197+
})
198+
}, [baseParams, pageParamKey])
185199

186200
useEffect(() => {
187201
if (needLoad) {
188-
const defaultOnSuccessOrError = () => {}
189-
const onSuccessLoad = onSuccessRef.current ?? defaultOnSuccessOrError
190-
const onFailedLoad = onErrorRef.current ?? defaultOnSuccessOrError
202+
const onSuccessLoad = getOnSuccessRef.current
203+
const onFailedLoad = getOnErrorRef.current
191204
request
192205
.load()
193206
.then(async result => {
194-
if (getNextPageRef.current) {
195-
nextPageRef.current = getNextPageRef.current(
196-
result,
197-
paramsRef.current,
198-
) as typeof nextPageRef.current
199-
}
207+
nextPageRef.current = getNextPageFnRef.current(
208+
result,
209+
getParamsRef.current(),
210+
) as typeof page
200211
await onSuccessLoad(result)
201212
})
202213
.catch(onFailedLoad)
203214
}
204215
optimisticIsLoadingRef.current = false
205216
}, [needLoad, request])
206217

207-
const loadMore = useCallback(() => {
208-
setPage(nextPageRef.current)
209-
}, [])
218+
useEffect(() => {
219+
getParamsRef.current = () => ({
220+
...baseParams,
221+
[pageParamKey]: nextPageRef.current,
222+
})
223+
}, [baseParams, pageParamKey])
224+
useEffect(() => {
225+
getOnSuccessRef.current = (...params) => onSuccess?.(...params)
226+
}, [onSuccess])
227+
useEffect(() => {
228+
getOnErrorRef.current = err => onError?.(err) ?? onGlobalError?.(err)
229+
}, [onError, onGlobalError])
230+
useEffect(() => {
231+
getNextPageFnRef.current = (...params) =>
232+
getNextPage ? getNextPage(...params) : undefined
233+
}, [getNextPage])
210234

211235
const data = useMemo<UseInfiniteDataLoaderResult<ResultType, ErrorType>>(
212236
() => ({

0 commit comments

Comments
 (0)