Реагируйте на customHook, используя useEffect с async - PullRequest
0 голосов
/ 05 августа 2020

У меня есть customHook с использованием useEffect, и я хотел бы, чтобы он возвращал результат после выполнения useEffect, однако он всегда возвращается до того, как мой метод asyn c будет выполнен ...

// customHook
const useLoadData = (startLoading, userId, hasError) => {
  const [loadDone, setLoadDone] = useState(false);
  const loadWebsite = async(userId) => {
     await apiService.call(...);
     console.log('service call is completed');
     dispatch(someAction);
  }

  useEffect(() => {
    // define async function inside useEffect
    const loadData = async () => {
       if (!hasError) {
          await loadWebsite();
       }
    }

    // call the above function based on flag
    if (startLoading) {
       await loadData();
       setLoadDone(true);
    } else {
      setLoadDone(false);
    }
  }, [startLoading]);

  return loadDone;
}

// main component
const mainComp = () => {
   const [startLoad, setStartLoad] = useState(true);
   const loadDone = useLoadData(startLoad, 1, false);
   useEffect(() => {
       console.log('in useEffect loadDone is: ', loadDone);
       if (loadDone) {
          // do something
          setStartLoad(false); //avoid load twice
       } else {
          // do something
       }
   }, [startLoad, loadDone]);
   useAnotherHook(loadDone); // this hook will use the result of my `useLoadData` hook as an execution flag and do something else, however, the `loadDone` always false as returning from my `useLoadData` hook
}

Кажется, что в моем хуке useDataLoad он не дожидается завершения моей asyn c функции loadData, а всегда возвращает loadDone как false, даже если я поместил ключевое слово await в свою функцию loadData и setLoadDone(true) после этого он по-прежнему всегда возвращает false, что было бы не так с моей реализацией здесь и как я могу вернуть правильное значение с помощью метода asyn c внутри customHook?

1 Ответ

0 голосов
/ 05 августа 2020

Ну ... похоже, он работает после того, как я поместил setLoadDone(true); в свой метод asyn c, а не внутри useEffect, хотя я не уверен, почему ... обновленный код:

// customHook
const useLoadData = (startLoading, userId, hasError) => {
  const [loadDone, setLoadDone] = useState(false);
  const loadWebsite = async(userId) => {
     await apiService.call(...);
     console.log('service call is completed');
     dispatch(someAction);
     setLoadDone(true);
  }

  useEffect(() => {
    // define async function inside useEffect
    const loadData = async () => {
       if (!hasError) {
          await loadWebsite();
       }
    }

    // call the above function based on flag
    if (startLoading) {
       await loadData();
       // setLoadDone(true); doesn't work here
    }
  }, [startLoading]);

  return loadDone;
}
...