Используйте ErrorBoundary вместе с асинхронными функциями жизненного цикла - PullRequest
0 голосов
/ 25 апреля 2018

Я хочу построить React-компонент, который асинхронно загружает данные на componentDidMount.

Вот как выглядит функция в данный момент (записано в TypeScript):

async componentDidMount(): Promise<void> {
    try {
        const { props: { teamId }, state: { } } = this;
        const awaitableData = await UrlHelper.getDataAsync("some-fancy-url");

        // ... do something with awaitableData
    } catch(e) {
        console.log("Some error occured");
        throw e;
    }
}

Функция render возвращает разметку, заключенную в компонент ErrorBoundary, в котором реализован componentDidCatch.Однако, это никогда не вызывается / запускается, когда ожидаемый вызов отклоняется, и я оказываюсь в catch -блоке.

Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

async функция является синтаксическим сахаром для обычной функции, которая возвращает обещание. Ошибка в функции async приводит к отклонению обещания. Даже если отклоненное обещание нигде не обработано и приводит к ошибке Uncaught (in promise), оно не попадает в границы ошибки.

Как ссылка состояний,

Границы ошибок не перехватывают ошибки для: <...> асинхронного кода (например, обратных вызовов setTimeout или requestAnimationFrame)

Решение состоит в том, чтобы изменить состояние компонента при ошибке и обработать его при следующем рендеринге. render - это место, где ошибка может быть вызвана синхронно.

Пример :

  state = { error: null };

  async componentDidMount() {
    try {
      await new Promise(resolve => setTimeout(resolve, 2000));
      throw new Error('Foo error');
    } catch (error) {
      this.setState({ error });
    }
  }

  render() {
    if (this.state.error) {
      throw this.state.error;
    }

    return (
      <p>Foo</p>
    );
  }
0 голосов
/ 25 апреля 2018

Давайте посмотрим на Документацию

в основном это говорит:

Границы ошибок - это компоненты React, которые отлавливают ошибки JavaScript где-нибудь в их дереве дочерних компонентов, регистрируйте эти ошибки и отображайте резервный пользовательский интерфейс вместо сбойного дерева компонентов. ошибка границы перехватывают ошибки во время рендеринга, в методах жизненного цикла и в Конструкторы всего дерева под ними.

так что, в основном, когда вы пытаетесь использовать ASYNC / AWAIT, и он терпит неудачу, он выходит на сторону CATCH вашей функции:

catch(e) {
    console.log("Some error occured");
    throw e;
}

и ошибка не будет выдана componentDidMount. на самом деле, если вы удалите метод try catch, componentDidMount позаботится об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...