Что такое Error Boundary и зачем он нужен

post_post_title__ZXHn9

Всем привет! Сегодня я затрону такой паттерн как Error Boundary в React, зачем он нужен и какую проблему решает. Программирование сложная штука, и никогда не знаешь откуда может прилететь баг, а багов бывает много и бывают они довольно странные. Не так просто бывает быстро найти ошибку и исправить ее. Разработчикам нужно много дебажить в поисках сложного бага:)

Так вот, в реакте есть такая техника как error boundary. Она выглядит как компонент, который обарачивает наше приложение и отлавливает ошибки в любом дочернем компоненте в приложении.

const App = () => (
 <ErrorBoundary>
     <Header />
     <Content />
     <Footer />
 </ErrorBoundary>
);
ReactDOM.render(<App />, document.getElementById("app"));

То есть, даже если у нас что-то сломается в самом, глубоко вложенном компоненте, компонент error boundary все равно его отловит и отрисует, то что мы вернем в методе render этого компонента, а не белый экран и красную консоль. То-есть error boundary это как кастомный интерфейс при ситуации, когда наше приложение сломалось. Мы будем рендерить что то, более красивое чем вот это в dev режиме

error boundary example

Здесь я хотел бы пояснить, что мы не сможем реализовать error boundary на хуках в реакте, так как альтернативы методу componentDidCatch пока что нету. Поэтому мы напишем вот такой класс:

export default class ErrorBoundary extends React.Component<{}, TState> {
 constructor(props) {
   super(props);
   this.state = { hasError: false };
 }
 static getDerivedStateFromError(error) {
   console.error(error);
   return { hasError: true };
 }
 componentDidCatch() {}
 render() {
   if (this.state.hasError) {
     return <h1
       style={{ color: 'red', display: 'flex', justifyContent: 'center' }}>
         App crashed
       </h1>;
   }
   return this.props.children;
 }
}

componentDidCatch вызывается всегда, когда у нас возникает ошибка, тем самым мы можем отловить ее, но в данном примере оставим этот метод пустым. Здесь нам поможет другой метод, а именно getDerivedStateFromError. В конструкторе мы объявим state и скажем что переменная hasError будет в значении false. Но если мы поймали ошибку в приложении, тогда в методе getDerivedStateFromError мы поменяем состояние на hasError: true. Тем самым наш компонент отрисует какой-то кастомный UI для ошибок. В нашем случае это просто заголовок красного цвета.

<h1 style={{ color: 'red', display: 'flex', justifyContent: 'center' }}>
 App crashed
</h1>;

В противном случае мы будем рендерить наше приложени просто возвращая:

this.props.children;

Вот такая простая и полезная штука есть в реакте, как обработка кастомных ошибок в UI. Надеюсь вы узнали что-то новое, и будете пользоваться и применять error boundary в своих production приложениях.