Изменение того, какой компонент возвращается после завершения длительной операции

#reactjs #async-await #promise

Вопрос:

Мой компонент выглядит так:

 export default function MyComponent(){        
    //long async operation
    //return something that is set inside the async operation
}
 

Поскольку асинхронная операция занимает некоторое время, return оператор выполняется до завершения асинхронной задачи, поэтому он возвращает что-то неполное.

Как я могу изменить то, что компонент возвращает после произвольно длительной асинхронной операции (или обещания), которая даст мне некоторые результаты после завершения?

Комментарии:

1. Существует более широкое, более идиоматичное (и более удобное для пользователя) решение. Когда вам нужно извлечь данные, вы должны поддерживать некоторое состояние, т. Е. загружаются ли данные или завершили извлечение. В зависимости от этого состояния вы показываете загружаемый пользовательский интерфейс, затем обновляете состояние/повторно отправляете, когда будете готовы показать содержательный пользовательский интерфейс

Ответ №1:

Используйте состояние для определения момента загрузки/завершения/сбоя данных

 export default function MyComponent(){
   const [loading, setLoading] = React.useState(false);
   const [data, setData] = React.useState(null);
   const [error, setError] = React.useState(null);
   React.useEffect(() => {
      setLoading(true);
      longAsyncOperation()
        .then((data) => {
            setData(data);
        })
        .catch((error) => {
            setError(error);
        })
        .finally(() => {
            setLoading(false);
        });
   }, []);        
 
   return isLoading 
      ? (<div>Loading</div>) 
      : error || !data ? (<div>{error.message}</div>)
      : (<div>Complete!</div>)

}
 

Ответ №2:

Вы должны использовать состояние и обновить его после завершения асинхронной операции:

 export default function MyComponent(){
  const [loading, setLoading] = useState();        
  setLoading(true);
    //long async operation
  setLoading(false);//this should run once the async operation has finished
    //return something that is set inside the async operation
  return loading ? <LoadingComponent /> : <MyView />;
}