Add Promisable type and allow it as an argument to useAsync.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline was successful
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	ci/woodpecker/push/woodpecker Pipeline was successful
				
			This commit is contained in:
		
							parent
							
								
									76182885db
								
							
						
					
					
						commit
						f1f8420de8
					
				
					 1 changed files with 17 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
import React, {useEffect, useState} from "react";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A type that can be returned by a promise or as is.
 | 
			
		||||
 */
 | 
			
		||||
export type Promisable<T> = T|Promise<T>;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Asynchronous data state.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +17,7 @@ interface AsyncState<T>
 | 
			
		|||
	/**
 | 
			
		||||
	 * The promise which is retrieved (or has retrieved) data.
 | 
			
		||||
	 */
 | 
			
		||||
	promise: Promise<T>;
 | 
			
		||||
	promise: Promisable<T>;
 | 
			
		||||
	/**
 | 
			
		||||
	 * Error thrown by the promise.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -33,20 +38,20 @@ export type PromiseFn<T> = () => Promise<T>;
 | 
			
		|||
 * @param promise The promise or a function that produces a promise.
 | 
			
		||||
 * @param deps When one of the `deps` change, it will wait for the promise again.
 | 
			
		||||
 */
 | 
			
		||||
export function useAsync<T>(promise: Promise<T>|PromiseFn<T>, deps: any[] = []): AsyncState<T>
 | 
			
		||||
export function useAsync<T>(promise: Promisable<T>|PromiseFn<T>, deps: any[] = []): AsyncState<T>
 | 
			
		||||
{
 | 
			
		||||
	// Get the actual promise from the function if there is one.
 | 
			
		||||
	if ((promise as PromiseFn<T>)?.call)
 | 
			
		||||
		promise = (promise as PromiseFn<T>)();
 | 
			
		||||
	else
 | 
			
		||||
	else if (promise instanceof Promise)
 | 
			
		||||
		promise = Promise.race([promise as Promise<T>]);
 | 
			
		||||
 | 
			
		||||
	// The async state.
 | 
			
		||||
	const [state, setState] = useState<AsyncState<T>>({
 | 
			
		||||
		pending: true,
 | 
			
		||||
		promise: promise,
 | 
			
		||||
		pending: promise instanceof Promise,
 | 
			
		||||
		promise: promise as Promisable<T>,
 | 
			
		||||
		error: undefined,
 | 
			
		||||
		data: undefined,
 | 
			
		||||
		data: promise instanceof Promise ? undefined : promise as T,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +65,11 @@ export function useAsync<T>(promise: Promise<T>|PromiseFn<T>, deps: any[] = []):
 | 
			
		|||
 | 
			
		||||
	// Reconfigure the promise when any deps have changed.
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
		(promise as Promise<T>).then((result) => {
 | 
			
		||||
		if (!(promise instanceof Promise))
 | 
			
		||||
			// If it's not a promise, there is nothing to wait for.
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		promise.then((result) => {
 | 
			
		||||
			// When there is a result, disable pending state and set retrieved data, without error.
 | 
			
		||||
			updateState({
 | 
			
		||||
				pending: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +88,7 @@ export function useAsync<T>(promise: Promise<T>|PromiseFn<T>, deps: any[] = []):
 | 
			
		|||
		// Promise is ready: reset the state to pending with the configured promise, without data and error.
 | 
			
		||||
		updateState({
 | 
			
		||||
			pending: true,
 | 
			
		||||
			promise: promise as Promise<T>,
 | 
			
		||||
			promise: promise,
 | 
			
		||||
			error: undefined,
 | 
			
		||||
			data: undefined,
 | 
			
		||||
		});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue