捕获到具有错误边界的错误后,如何使用react-router?

时间:2019-07-17 15:42:43

标签: javascript reactjs error-handling react-router

我有一个简单的react应用程序(使用create-react-app创建),它使用react-router在作为我的应用程序“主体”的组件之间导航。我最近开始研究错误处理,并遇到了错误边界。当用户遇到错误时,我仍然希望显示应用程序的外壳(用于导航),其中的正文由错误消息替换。目前,我有以下代码:

index.js:

...
ReactDOM.render(
    <Provider store={store}>
        <Router>
            <App />
        </Router>
    </Provider>,
    document.getElementById('root')
);

App.js:

...
function App() {
    return (
        <div className="container">
            <Header />
            <ErrorBoundary>
                <Switch>
                    <Route exact path="/" component={UnderConstruction} />
                    <Route path="/pas" component={PAS} />
                    <Route path="/github/:user" component={GithubPage} />
                    <Route path="/reddit" component={RedditPage} />
                </Switch>
            </ErrorBoundary>
        </div>
    );
}

Header.js:

const links = [
    { link: '/', linkText: 'Home' },
    { link: '/pas', linkText: 'PAS' },
    { link: '/github', linkText: 'Github' },
    { link: '/reddit', linkText: 'Reddit' }
];

const Header = () => {
    const activeStyle = { color: '#f15b2a' };
    return (
        <nav className="row text-center mb-3">
            <div className="col-12">
                {links.map(({ link, linkText }) => (
                    <NavLink
                        to={link}
                        key={link}
                        exact
                        activeStyle={activeStyle}
                        className="btn btn-dark">
                        {linkText}
                    </NavLink>
                ))}
            </div>
        </nav>
    );
};

ErrorBoundary.js:

...
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { error: null, eventID: null };
    }

    componentDidCatch(error, errorInfo) {
        this.setState({ error });
        Sentry.withScope(scope => {
            scope.setExtras(errorInfo);
            const eventID = Sentry.captureException(error);
            this.setState({ eventId: eventID });
        });
    }

    handleReportClick = e => {
        e.preventDefault();
        Sentry.showReportDialog({ eventId: this.state.eventId });
    };

    render() {
        if (this.state.error) {
            //Render fallback UI
            return <ErrorPage onReportClick={this.handleReportClick} />;
        } else {
            //When there's not an error, render the children untouched
            return this.props.children;
        }
    }
}

ErrorPage.js:

...
const ErrorPage = ({ onReportClick, ...props }) => {
    return (
        <>
            <div className="row mb-3">
                <div className="col-12 text-center">
                    <h1 className="display-4">
                        An error has been encountered.
                    </h1>
                </div>
            </div>
            <div className="row">
                <div className="col-6 text-center">
                    <button
                        className="btn btn-lg btn-outline-info"
                        onClick={onReportClick}>
                        Report feedback
                    </button>
                </div>
                <div className="col-6 text-center">
                    <a
                        href={process.env.REACT_APP_ENVIRONMENT_URL}
                        className="btn btn-lg btn-outline-info">
                        Go back to the worklist
                    </a>
                </div>
            </div>
        </>
    );
};

由于<Header />超出了App.js的错误范围,因此我希望它能够显示出来并提供从错误页面导航的功能。标题显示在错误页面上,单击导航链接可更改URL;但是,该应用程序实际上并没有进入其他任何页面,它只是位于错误页面上。

1 个答案:

答案 0 :(得分:0)

您可以将Header包装在withRouter HOC中。这样,组件可以“知道” react-router。这样,Link中的react-router组件应表现出预期的效果。