Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "http-react",
"version": "3.0.2",
"version": "3.0.4",
"description": "React hooks for data fetching",
"main": "dist/index.js",
"scripts": {
Expand Down
26 changes: 15 additions & 11 deletions src/hooks/others.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,17 @@ export function useFetchCode(id: any) {
* Get the loading state of a request using its id
*/
export function useFetchLoading(id: any): boolean {
const idString = serialize({ idString: serialize(id) })

const { loading } = useFetch({
id: id
const { loading, ...all } = useFetch({
id
})

return !isDefined(runningRequests[idString]) ? true : isPending(idString)
return (
loading &&
isPending(
serialize({
idString: serialize(id)
})
)
)
}

/**
Expand All @@ -159,11 +163,11 @@ export function useFetchError(id: any, onError?: (err?: any) => void) {
}
}, [resolvedKey])

const { error } = useFetch({
id: id
})

return error
return (
useFetch({
id: id
}).error || hasErrors[resolvedKey]
)
}

/**
Expand Down
138 changes: 59 additions & 79 deletions src/hooks/use-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
loading: auto
? isPending(resolvedKey) ||
(revalidateOnMount
? suspense
? isPending(resolvedKey)
: true
? previousConfig[resolvedKey] !== serialize(optionsConfig)
: previousConfig[resolvedKey] !== serialize(optionsConfig))
: false,
error: (hasErrors[resolvedDataKey] || false) as boolean,
Expand All @@ -337,7 +335,11 @@ export function useFetch<FetchDataType = any, BodyType = any>(
loading: false,
error: false,
completedAttempts: false
})
}).current

const inDeps = (k: keyof typeof thisDeps) => {
return thisDeps[k]
}

const { data, loading, online, error, completedAttempts } = fetchState

Expand Down Expand Up @@ -833,32 +835,10 @@ export function useFetch<FetchDataType = any, BodyType = any>(
}
}
} finally {
setFetchState(p => {
const n = {
...p,
data: thisDeps.current.data ? $$data ?? p.data : p.data,
online: thisDeps.current.online ? p.online : p.online,
loading: thisDeps.current.loading
? rpc?.loading ?? false
: p.loading,
error: thisDeps.current.error
? isDefined($$error)
? $$error
: p.error
: p.error,
completedAttempts: thisDeps.current.completedAttempts
? $$completedAttempts ?? p.completedAttempts
: p.completedAttempts
}
if (jsonCompare(n, p)) return p
return n
})

runningRequests[resolvedKey] = false
suspenseInitialized[resolvedKey] = true

requestsProvider.emit(resolvedKey, {
requestCallId,
error:
hasErrors[resolvedKey] || hasErrors[resolvedDataKey] || false,
...rpc,
Expand All @@ -875,7 +855,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
}
},
[
thisDeps.current,
thisDeps,
canRevalidate,
ctx.auto,
stringDeps,
Expand Down Expand Up @@ -960,28 +940,21 @@ export function useFetch<FetchDataType = any, BodyType = any>(
if (v.requestCallId !== requestCallId) {
if (!willSuspend[resolvedKey]) {
queue(() => {
setFetchState(p => {
const n = {
...p,
data: thisDeps.current.data
? !jsonCompare($data, p.data)
? $data
: p.data ?? p.data
: p.data,
online: thisDeps.current.online ? online ?? p.online : p.online,
loading: thisDeps.current.loading
? loading ?? p.loading
: p.loading,
error: thisDeps.current.error ? Boolean($error) : p.error,
completedAttempts: thisDeps.current.completedAttempts
? completedAttempts ?? p.completedAttempts
: p.completedAttempts
}

if (jsonCompare(n, p)) return p

return n
})
if (inDeps('data')) {
setData($data)
}
if (inDeps('online')) {
setOnline(online)
}
if (inDeps('loading')) {
setLoading(loading)
}
if (inDeps('error')) {
setError($error)
}
if (inDeps('completedAttempts')) {
setCompletedAttempts(completedAttempts)
}
})
}
}
Expand All @@ -993,7 +966,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
requestsProvider.removeListener(resolvedKey, waitFormUpdates)
}
}, [
thisDeps.current,
thisDeps,
JSON.stringify(optionsConfig),
resolvedKey,
resolvedDataKey,
Expand Down Expand Up @@ -1172,7 +1145,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
online: false,
error: true
})
if (thisDeps.current.online) setOnline(false)
if (inDeps('online')) setOnline(false)
}
}
}, getMiliseconds(attemptInterval as TimeSpan))
Expand Down Expand Up @@ -1225,22 +1198,25 @@ export function useFetch<FetchDataType = any, BodyType = any>(
}
return d
},
[serialize(serialize(optionsConfig)), fetchState]
[serialize(serialize(optionsConfig)), fetchState, thisDeps]
)

if (!suspense) {
if (url !== '') {
suspenseInitialized[resolvedKey] = true
}
}
useEffect(() => {

React.useLayoutEffect(() => {
if (url !== '') {
if (!jsonCompare(previousProps[resolvedKey], optionsConfig)) {
abortControllers[resolvedKey]?.abort()
queue(initializeRevalidation)
if (inDeps('data')) {
queue(initializeRevalidation)
}
}
}
}, [serialize(optionsConfig)])
}, [serialize(optionsConfig), thisDeps])

if (suspense) {
if (auto) {
Expand All @@ -1260,30 +1236,34 @@ export function useFetch<FetchDataType = any, BodyType = any>(
}
}

React.useMemo(() => {
React.useLayoutEffect(() => {
if (!runningRequests[resolvedKey] && isExpired) {
if (windowExists) {
if (canRevalidate && url !== '') {
if (!jsonCompare(previousConfig[resolvedKey], optionsConfig)) {
if (!isPending(resolvedKey)) {
initializeRevalidation()
if (inDeps('data')) {
initializeRevalidation()
}
} else {
setLoading(true)
}
}
}
}
}
}, [resolvedKey, serialize(optionsConfig), canRevalidate])
}, [resolvedKey, serialize(optionsConfig), canRevalidate, thisDeps])

useEffect(() => {
React.useLayoutEffect(() => {
const revalidateAfterUnmount = revalidateOnMount
? true
: previousConfig[resolvedKey] !== serialize(optionsConfig)

function revalidate() {
if (!debounce && !canDebounce[resolvedKey]) {
initializeRevalidation()
if (inDeps('data')) {
initializeRevalidation()
}
}
}

Expand All @@ -1298,7 +1278,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [serialize(optionsConfig)])
}, [serialize(optionsConfig), thisDeps])

useEffect(() => {
function addFocusListener() {
Expand Down Expand Up @@ -1411,7 +1391,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
? new Date(cacheProvider.get('expiration' + resolvedDataKey))
: null

const isFailed = hasErrors[resolvedDataKey] || error
const isFailed = hasErrors[resolvedDataKey] || hasErrors[resolvedKey] || error

const responseData =
(error && isFailed ? (cacheIfError ? thisCache : null) : thisCache) ?? def
Expand All @@ -1426,64 +1406,64 @@ export function useFetch<FetchDataType = any, BodyType = any>(

return {
get revalidating() {
thisDeps.current.loading = true
thisDeps.loading = true
return oneRequestResolved && isLoading
},
get hasData() {
thisDeps.current.data = true
thisDeps.data = true
return oneRequestResolved
},
get success() {
thisDeps.current.loading = true
thisDeps.current.error = true
thisDeps.loading = true
thisDeps.error = true
return isSuccess
},
get loadingFirst() {
thisDeps.current.loading = true
thisDeps.loading = true
return loadingFirst
},
get requestStart() {
thisDeps.current.loading = true
thisDeps.loading = true
return getDateIfValid($requestStart)
},
get requestEnd() {
thisDeps.current.loading = true
thisDeps.loading = true
return getDateIfValid($requestEnd)
},
get expiration() {
thisDeps.current.loading = true
thisDeps.loading = true
return getDateIfValid(isFailed ? null : expirationDate)
},
get responseTime() {
thisDeps.current.loading = true
thisDeps.loading = true
return requestResponseTimes[resolvedDataKey] ?? null
},
get data() {
thisDeps.current.data = true
thisDeps.data = true
return responseData
},
get loading() {
thisDeps.current.loading = true
thisDeps.loading = true
return isLoading
},
get error() {
thisDeps.current.error = true
thisDeps.error = true
return isFailed || false
},
get online() {
thisDeps.current.online = true
thisDeps.online = true
return online
},
get code() {
thisDeps.current.loading = true
thisDeps.loading = true
return statusCodes[resolvedKey]
},
get reFetch() {
thisDeps.current.loading = true
thisDeps.loading = true
return reValidate
},
get mutate() {
thisDeps.current.data = true
thisDeps.data = true
return forceMutate
},
get fetcher() {
Expand All @@ -1508,7 +1488,7 @@ export function useFetch<FetchDataType = any, BodyType = any>(
},
config: __config,
get response() {
thisDeps.current.loading = true
thisDeps.loading = true
return lastResponses[resolvedKey]
},
id,
Expand Down