React ErrorBoundary - просто не могу заставить его работать - PullRequest
0 голосов
/ 23 февраля 2019

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

Мне просто нужно знать, как ловить ошибки в React простым и понятным способом.Я использую CRA 2.0 / React 16.7.Мне нужен блок try / catch на уровне действий, так как именно здесь бизнес-логика сконцентрирована в моем приложении.

Я прочитал это и реализовал, как описано, но мой объект ErrorBoundary никогда не перехватывает ошибки.

Пример:

import React, { Component } from "react";

class ErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

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

    componentDidCatch(error, info) {
        console.log("ErrorBoundary: ", error);
        console.log("ErrorBoundary: ", info);
    }

    render() {
        if (this.state.hasError) {
            return <h1>Something went wrong.</h1>;
        }
        return this.props.children;
    }
}

export default ErrorBoundary;

Я обертываю свои маршруты на верхнем уровне:

    return (
        <BrowserRouter>
            <ErrorBoundary>
                <div className="main-container">
                    <SideBar />
                    <div className="some-class">
                        <Switch>
                            <Route path="/events" component={Events} />
                            <Route exact path="/" component={Index} />
                        </Switch>
                    </div>
                </div>
            </ErrorBoundary>
        </BrowserRouter>
    );

В «событиях» выше я делаю вызов API, который выбрасывает 500ошибка на стороне API:

componentDidMount() {
    this.props.getAllEvents();
}

Вот действие Redux:

export const getAllEvents = () => {
    return async (dispatch, getState) => {
        try {
            let state = getState();
            const result = await get({
                state: state,
                route: "/v1/events"
            });
            dispatch({
                type: GET_EVENTS,
                payload: result
            });
        } catch (e) {
            console.log("Something went wrong at action...");
        }
    };
};

... "get ()" - это просто упаковка Axios GET - ничего особенного.

Я вижу ошибку 500 в консоли из-за неудачного вызова API.Я никогда не видел «Что-то пошло не так ...» в консоли, из блока catch выше, хотя эта строка действительно ударилась во время отладки.

Метод componentDidCatch () никогда не вызывается - hasError"всегда ложно, и это всегда отрисовывает дочерние элементы.

Если я удаляю блок throw в конечной точке API, все работает нормально, и я получаю свои данные.Я просто не могу ловить ошибки на уровне пользовательского интерфейса.Я попытался попробовать / поймать в "componentDidMount ()", я попытался удалить блок try / catch в действии ... поведение не меняется.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Как правильно сказал другой ответ, граница ошибок React будет перехватывать только ошибки рендеринга.

Поскольку вы используете redux, вы можете создать свой собственный механизм для таких случаев, как ваш:

  1. Всякий раз, когда возникает ошибка, вы отправляете действие со свойством error.
  2. Редуктор ищет только те действия, которые имеют свойство error.Он получает действие и обновляет состояние «глобальной ошибки» в дереве состояний.
  3. Компонент оболочки connect ed для всего приложения видит это изменение состояния и отображает резервный пользовательский интерфейс.

Например:
Отправьте действие со свойством error:

export const getAllEvents = () => {
    return async (dispatch, getState) => {
        try {
            ...
        } catch (e) {
            dispatch({
                type: ERROR, 
                error: e // dispatch an action that has `error` property
            });
        }
    };
};

Редуктор увидит его и обновит state.error часть:

export default function errorReducer(state = null, action) {
  const { type, error } = action;
  if (type === RESET_ERROR_MESSAGE) {  // an action to clear the error
    return null;
  } else if (error) { // any type of action, but contains an `error`
    return error;
  }
  return state;
}

Теперь вы заверните свойприложение на границе connected:

function Wrapper({error}) {
  if(error) return <h1>Something went wrong</h1>;
  return <App/>;
}

export default connect(
  state => ({
    error: state.error,
  })
)(Wrapper);
0 голосов
/ 23 февраля 2019

Из документов React Error Границы :

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

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