кодесурса
«Реагировать

Границы ошибок

script1adsense2code
script1adsense3code

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

Введение в границы ошибок

Инженеры React считают, что ошибки JavaScript, являющиеся частью пользовательского интерфейса, не должны нарушать работу всего приложения. Чтобы решить эту проблему для пользователей React, в React 16 вводится новая концепция «границы ошибок».

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

Заметка

Границы ошибок не перехватывают ошибки для:

  • Обработчики событий.
  • Асинхронный код (например, setTimeout, requestAnimationFrame или обратные вызовы)
  • Рендеринг на стороне сервера
  • Ошибки выбрасываются в самой границе ошибки (а не в ее дочерних элементах)

Компонент класса становится границей ошибки, если он определяет (или оба) из методов жизненного цикла static getDerivedStateFromError () или componentDidCatch ().

Используйте статический метод getDerivedStateFromError () для визуализации резервного интерфейса после возникновения ошибки. Используйте componentDidCatch () для регистрации информации об ошибках.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }
  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

Тогда вы можете использовать его как обычный компонент:

<ErrorBoundary>
<MyWidget />
</ErrorBoundary>

Границы ошибок работают как JavaScript-блок catch {}, но для компонентов. Только компоненты класса могут быть границами ошибок. На практике большую часть времени вы захотите объявить компонент границы ошибки один раз и использовать его в своем приложении.

Обратите внимание, что границы ошибок перехватывают ошибки только в компонентах под ними в дереве. Граница ошибки не может поймать ошибку внутри себя. Если при попытке отобразить сообщение об ошибке граница ошибки не удалась, ошибка будет распространяться до ближайшей границы ошибки над ней. Это также похоже на то, как работает блок catch {} в JavaScript.

Где разместить границы ошибок

Детальность границ ошибок зависит от вас. Вы можете обернуть компоненты маршрута верхнего уровня, чтобы отобразить для пользователя сообщение «Что-то пошло не так», так же, как серверные инфраструктуры часто обрабатывают сбои. Вы также можете обернуть отдельные виджеты в границу ошибки, чтобы защитить их от сбоя остальной части приложения.

Новое поведение для необнаруженных ошибок

Это изменение имеет важное значение. Начиная с React 16, ошибки, которые не были обнаружены какой-либо границей ошибок, приведут к размонтированию всего дерева компонентов React.

Мы обсуждали это решение, но по нашему опыту хуже оставить поврежденный пользовательский интерфейс, чем полностью его удалить. Например, в таком продукте, как Messenger, оставление видимого испорченного пользовательского интерфейса может привести к тому, что кто-то отправит сообщение не тому человеку. Аналогично, для платежного приложения хуже отображать неправильную сумму, чем ничего не отображать.

Это изменение означает, что при переходе на React 16 вы, скорее всего, обнаружите существующие сбои в приложении, которые ранее не были замечены. Добавление границ ошибок позволяет улучшить взаимодействие с пользователем, если что-то идет не так.

Например, Facebook Messenger оборачивает содержимое боковой панели, информационной панели, журнала разговоров и ввода сообщений в отдельные границы ошибок. Если какой-либо компонент в одной из этих областей пользовательского интерфейса выходит из строя, остальные остаются интерактивными.

Мы также рекомендуем вам использовать службы отчетов об ошибках JS (или создавать свои собственные), чтобы вы могли узнать о необработанных исключениях, возникающих в процессе производства, и исправить их.

Следы стека компонентов

React 16 печатает все ошибки, возникшие во время рендеринга, на консоли в процессе разработки, даже если приложение случайно их проглотит. В дополнение к сообщению об ошибке и стеку JavaScript он также обеспечивает трассировку стека компонентов. Теперь вы можете увидеть, где именно в дереве компонентов произошел сбой:

Вы также можете увидеть имена файлов и номера строк в трассировке стека компонентов. Это работает по умолчанию в проектах Create React App:

Если вы не используете Create React App, вы можете добавить этот плагин вручную в конфигурацию Babel. Обратите внимание, что он предназначен только для разработки и должен быть отключен на производстве.

Заметка

Имена компонентов, отображаемые в трассировке стека, зависят от свойства Function.name. Если вы поддерживаете старые браузеры и устройства, которые еще не могут обеспечить это изначально (например, IE 11), подумайте о включении полизаполнения Function.name в ваше приложение, такое как function.name-polyfill. Кроме того, вы можете явно установить свойство displayName для всех ваших компонентов.

Как насчет попробовать / поймать?

try / catch is great but it only works for imperative code:
try {
  showButton();
} catch (error) {
  // ...
}

Однако компоненты React являются декларативными и указывают, что должно быть отображено:

<Button />

Границы ошибок сохраняют декларативный характер React и ведут себя так, как вы ожидаете. Например, даже если ошибка возникает в методе componentDidUpdate, вызванном setStatesomewhere глубоко в дереве, он все равно будет правильно распространяться до ближайшей границы ошибки.

Как насчет обработчиков событий?

Границы ошибок не перехватывают ошибки внутри обработчиков событий.

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

Если вам нужно перехватить ошибку внутри обработчика события, используйте обычный оператор try / catch для JavaScript:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    try {
      // Do something that could throw
    } catch (error) {
      this.setState({ error });
    }
  }
  render() {
    if (this.state.error) {
      return <h1>Caught an error.</h1>
    }
    return <div onClick={this.handleClick}>Click Me</div>
  }
}
Note that the above example is demonstrating regular JavaScript behavior and doesn?t use error boundaries.</p>

Новый контент: Composer: менеджер зависимостей для PHP , R программирования


script1adsense4code
script1adsense5code
disqus2code
script1adsense6code
script1adsense7code
script1adsense8code
buysellads2code