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";
 | 
					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.
 | 
					 * Asynchronous data state.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -12,7 +17,7 @@ interface AsyncState<T>
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The promise which is retrieved (or has retrieved) data.
 | 
						 * The promise which is retrieved (or has retrieved) data.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	promise: Promise<T>;
 | 
						promise: Promisable<T>;
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Error thrown by the promise.
 | 
						 * 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 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.
 | 
					 * @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.
 | 
						// Get the actual promise from the function if there is one.
 | 
				
			||||||
	if ((promise as PromiseFn<T>)?.call)
 | 
						if ((promise as PromiseFn<T>)?.call)
 | 
				
			||||||
		promise = (promise as PromiseFn<T>)();
 | 
							promise = (promise as PromiseFn<T>)();
 | 
				
			||||||
	else
 | 
						else if (promise instanceof Promise)
 | 
				
			||||||
		promise = Promise.race([promise as Promise<T>]);
 | 
							promise = Promise.race([promise as Promise<T>]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The async state.
 | 
						// The async state.
 | 
				
			||||||
	const [state, setState] = useState<AsyncState<T>>({
 | 
						const [state, setState] = useState<AsyncState<T>>({
 | 
				
			||||||
		pending: true,
 | 
							pending: promise instanceof Promise,
 | 
				
			||||||
		promise: promise,
 | 
							promise: promise as Promisable<T>,
 | 
				
			||||||
		error: undefined,
 | 
							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.
 | 
						// Reconfigure the promise when any deps have changed.
 | 
				
			||||||
	useEffect(() => {
 | 
						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.
 | 
								// When there is a result, disable pending state and set retrieved data, without error.
 | 
				
			||||||
			updateState({
 | 
								updateState({
 | 
				
			||||||
				pending: false,
 | 
									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.
 | 
							// Promise is ready: reset the state to pending with the configured promise, without data and error.
 | 
				
			||||||
		updateState({
 | 
							updateState({
 | 
				
			||||||
			pending: true,
 | 
								pending: true,
 | 
				
			||||||
			promise: promise as Promise<T>,
 | 
								promise: promise,
 | 
				
			||||||
			error: undefined,
 | 
								error: undefined,
 | 
				
			||||||
			data: undefined,
 | 
								data: undefined,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue