Correctly memoize the promise from a function depending on deps when using useAsync.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful

This commit is contained in:
Madeorsk 2024-09-24 23:04:11 +02:00
parent e2fc741fee
commit 1963b6208a
Signed by: Madeorsk
GPG key ID: 677E51CA765BB79F
2 changed files with 10 additions and 6 deletions

View file

@ -1,5 +1,5 @@
{ {
"version": "1.4.0", "version": "1.4.1",
"name": "@kernelui/core", "name": "@kernelui/core",
"description": "Kernel UI Core.", "description": "Kernel UI Core.",
"scripts": { "scripts": {

View file

@ -1,4 +1,4 @@
import React, {useEffect, useState} from "react"; import React, {useEffect, useMemo, useState} from "react";
/** /**
* A type that can be returned by a promise or as is. * A type that can be returned by a promise or as is.
@ -41,10 +41,14 @@ export type PromiseFn<T> = () => Promise<T>;
export function useAsync<T>(promise: Promisable<T>|PromiseFn<T>, deps: any[] = []): [AsyncState<T>, React.Dispatch<T>] export function useAsync<T>(promise: Promisable<T>|PromiseFn<T>, deps: any[] = []): [AsyncState<T>, React.Dispatch<T>]
{ {
// Get the actual promise from the function if there is one. // Get the actual promise from the function if there is one.
if ((promise as PromiseFn<T>)?.call) promise = useMemo(() => {
promise = (promise as PromiseFn<T>)(); if ((promise as PromiseFn<T>)?.call)
else if (promise instanceof Promise) return (promise as PromiseFn<T>)();
promise = Promise.race([promise as Promise<T>]); else if (promise instanceof Promise)
return Promise.race([promise as Promise<T>]);
else
return promise;
}, deps);
// The async state. // The async state.
const [state, setState] = useState<AsyncState<T>>({ const [state, setState] = useState<AsyncState<T>>({