usePromise.tsx 949 B

12345678910111213141516171819202122232425262728
  1. import { useState, useEffect, useCallback } from 'react';
  2. export type UsePromiseReturnValues<T> = [T, any, boolean, () => Promise<void|null>];
  3. export default function usePromise<T> (promise: () => Promise<T>, defaultValue: T, dependsOn: any[] = []): UsePromiseReturnValues<T> {
  4. const [state, setState] = useState<{
  5. value: T;
  6. error: any;
  7. isPending: boolean;
  8. }>({ value: defaultValue, error: null, isPending: true });
  9. let isSubscribed = true;
  10. const execute = useCallback(() => {
  11. return promise()
  12. .then(value => (isSubscribed ? setState({ value, error: null, isPending: false }) : null))
  13. .catch(error => (isSubscribed ? setState({ value: defaultValue, error: error, isPending: false }) : null));
  14. }, [promise]);
  15. useEffect(() => {
  16. execute();
  17. return () => {
  18. isSubscribed = false;
  19. };
  20. }, dependsOn);
  21. const { value, error, isPending } = state;
  22. return [value, error, isPending, execute];
  23. }