React-router перестает работать, когда граница ошибки обнаруживает ошибку в маршруте - PullRequest
0 голосов
/ 13 февраля 2020

Кодовый указатель, связанный с ниже, использует react-router и границу ошибки для обнаружения ошибок в каждом маршруте.

Если вы нажмете «Магазин», ошибка будет обнаружена, как и ожидалось, но другие ссылки тогда больше не работают. Что тут происходит? Почему react-router-dom перестает работать? Каков «правильный» способ сделать это? Это проблема с компонентом <ErrorBoundary>, или как упакованы компоненты маршрута, или? 100

https://codepen.io/mpontus/pen/NyKNoL


На случай, если что-то случится со ссылкой на кодовый блок:

const { BrowserRouter, Switch, Route, NavLink } = ReactRouterDOM;

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      return <h1>An error has occured.</h1>;
    }

    return this.props.children;
  }
}

const HomeScreen = () => <h3>Home</h3>;

const ProfileScreen = () => <h3>Profile Screen</h3>;

const ShopScreen = () => {
  throw new Error("Error during render");
};

const App = () => (
  <BrowserRouter>
    <div className="container">
      <nav className="nav nav-pills">
        <NavLink exact className="nav-link" activeClassName="active" to="/">
          Home
        </NavLink>
        <NavLink className="nav-link" activeClassName="active" to="/profile">
          Profile
        </NavLink>
        <NavLink className="nav-link" activeClassName="active" to="/shop">
          Shop
        </NavLink>
      </nav>
      <Switch>
        <Route
          exact
          path="/"
          render={() => (
            <ErrorBoundary>
              <HomeScreen />
            </ErrorBoundary>
          )}
        />
        <Route
          path="/profile"
          render={() => (
            <ErrorBoundary>
              <ProfileScreen />
            </ErrorBoundary>
          )}
        />
        <Route
          path="/shop"
          render={() => (
            <ErrorBoundary>
              <ShopScreen />
            </ErrorBoundary>
          )}
        />
      </Switch>
    </div>
  </BrowserRouter>
);

ReactDOM.render(<App />, document.getElementById("root"));

1 Ответ

0 голосов
/ 13 февраля 2020

Короче говоря, поскольку вы повторно используете ErrorBoundary для каждого маршрута, он никогда не отключается (это сделано специально). Таким образом, его состояние hasError сохраняется на каждом маршруте.

Вы можете уменьшить это, обновив состояние при изменении местоположения в компоненте ErrorBoundary:

  componentDidUpdate(prevProps) {
    if (prevProps.location.pathname !== this.props.location.pathname) {
      this.setState({ hasError: false });
    }
  }

Так как вы ' Чтобы использовать render реквизит, вам придется вручную передать маршрутные реквизиты компоненту ErrorBoundary:

Например:

<Route
  exact
  path="/"
  render={props => (
    <ErrorBoundary {...props}>
      <HomeScreen {...props} />
    </ErrorBoundary>
  )}
/>

Рабочая демонстрация (так как этот код и окно находятся в development, будет отображаться наложение ошибок, поэтому вам придется закрыть окно ошибок, чтобы продолжить):

Edit Error Boundary

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...