Home > Software design >  Solution to breakout a Promise outside a component
Solution to breakout a Promise outside a component

Time:10-26

Origin code

const getData = useCallback(async () => {
    dispatchAnimation(actionSetAnimationState(true));
    try {
      await Promise.all([getGroupData(), getPolicyData()]);
    } catch (err) {
      notifyError('error...');
    }
    dispatchAnimation(actionSetAnimationState(false));
  }, [dispatchAnimation, getGroupData, getPolicyData, localize]);

useEffect(() => {
    getData();
  }, [getData]);

I want to moving the try catch to another file

import { useCallback } from 'react';

import { actionSetAnimationState } from '../reducer/animation/animationAction';
import { useAnimation } from '../reducer/useStore';
import doSleep from './doSleep';
import { notifyError } from './Toast';

async function CustomCallbackWithAnimation(argv: Array<Promise<void>>): Promise<void> {
  const { dispatchAnimation } = useAnimation();

  dispatchAnimation(actionSetAnimationState(true));
  useCallback(async () => {
    try {
      await Promise.all(argv);
    } catch (err) {
      notifyError('error');
    }
  }, [argv]);
  dispatchAnimation(actionSetAnimationState(false));
}

export default CustomCallbackWithAnimation;


In .tsx file that need to getData just calling

 useEffect(() => {
    CustomCallbackWithAnimation([getGroupData(), getPolicyData()]);
  }, [edit]);

But I am receiving this error Error: Invalid hook call. Hooks can only be called inside of the body of a function component

Do you have any solution that better to split this function(meaning I want to reused it any where to avoid duplicate code)?

I want to reused it any where to avoid duplicate code

CodePudding user response:

Instead directly call CustomCallbackWithAnimation that runs hooks inside, make it return callback that you can invoke where you want later.

Something like that

export function useCustomCallback() {
  const { dispatchAnimation } = useAnimation();

  return useCallback(async (argv: Array<Promise<void>>) => {
    dispatchAnimation(actionSetAnimationState(true));
    try {
      await Promise.all(argv);
    } catch (err) {
      notifyError('error');
    }
    dispatchAnimation(actionSetAnimationState(false));
  }, [argv])
}

const App = () => {
  const callback = useCustomCallback()

  useEffect(() => {
    callback([firstPromise, secondPromise])
  }, [])

  return <div></div>
}
  • Related