Граница ошибки React не предотвращает сбой приложения cra

Я хочу создать границу ошибки, которая предотвратит сбой всего моего приложения, а скорее проинформирует пользователя о том, что что-то пошло не так, и предоставит ему возможность перезагрузить страницу. Мой компонент границы ошибки:

import React, { Fragment, PureComponent } from "react";
import { withRouter, RouteComponentProps } from "react-router";

type Props = RouteComponentProps;

type State = { hasError: boolean; };

class RootErrorBoundary extends PureComponent<Props, State> {
  state: State = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  reloadPage = () => {
    this.setState({ hasError: false });
    const { history } = this.props;
    history.go(0);
  };

  renderOnError = () => {
    return (
      <Fragment>
        Somthing went wrong!
        <button onClick={this.reloadPage}>Click here to reload</button>
      </Fragment>
    );
  };

  render() {
    if (this.state.hasError) {
      return this.renderOnError();
    }

    return this.props.children;
  }
}

export default withRouter(RootErrorBoundary);

Реализую это так:

// index.jsx
// ...

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <StylesProvider injectFirst>
        <ConnectedThemeProvider>
          <RootErrorBoundary>
            <App />
          </RootErrorBoundary>
        </ConnectedThemeProvider>
      </StylesProvider>
    </Router>
  </Provider>,
  rootElement
);

А затем где-то глубоко внутри моего дерева компонентов приложения я определяю функцию для ручного запуска ошибки (для целей тестирования / прототипирования):

const [hasError, setHasError] = useState(false);
(window as any).kaboom = () => setHasError(true);
if (hasError) {
  setHasError(false);
  throw new Error("CUSTOM ERROR");
}

Когда я звоню window.kaboom()с консоли моя граница ошибки срабатывает правильно. Но как только я нажимаю кнопку перезагрузки, вместо обновления страницы та же ошибка перехватывается наложением ошибок cra и распечатывает трассировку стека:

Error: CUSTOM ERROR

TemplateTable
FILE_WITH_ERROR.tsx:96
  93 | (window as any).kaboom = () => setHasError(true);
  94 | if (hasError) {
  95 |   setHasError(false);
> 96 |   throw new Error("CUSTOM ERROR");
     | ^  
  97 | }
  98 | 
  99 | return (
View compiled
▶ 17 stack frames were collapsed.

TemplateTable.window.kaboom
FILE_WITH_ERROR.tsx:93
  90 | );
  91 | 
  92 | const [hasError, setHasError] = useState(false);
> 93 | (window as any).kaboom = () => setHasError(true);
     | ^  
  94 | if (hasError) {
  95 |   setHasError(false);
  96 |   throw new Error("CUSTOM ERROR");
View compiled
(anonymous function)
<anonymous>:1:1

Это почему? Я ожидал, что моя настраиваемая граница ошибки перехватит ошибку и не позволит ей распространяться дальше. И как я могу добиться того, чего хочу, и правильно протестировать свое решение?

1 ответ

Решение

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

Все, что мне нужно сделать, чтобы проверить свою границу, - это нажать escape как только он выскочит, чтобы закрыть его снова.

Кредит подходит к этому ответу: /questions/19080954/otklyuchit-nalozhenie-oshibok-v-rezhime-razrabotki/19080961#19080961

Другие вопросы по тегам