Реагировать на бесконечный рендер частного маршрута - Ошибка при получении: превышена максимальная глубина обновления - PullRequest
2 голосов
/ 29 января 2020

Я пытаюсь отобразить мои компоненты внутри частных маршрутов, если пользователь авторизован. Но я продолжаю получать ошибку. Ошибка: превышена максимальная глубина обновления. Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы.

Чтобы проверить, авторизован ли пользователь, я получаю токен из localStorage.

Закомментированная строка const authed = true предназначена для тестирования. и он работает.

Мой компонент Routes выглядит следующим образом:

import React from 'react';
import { Switch, Redirect, Route } from 'react-router-dom';

import { RouteWithLayout } from './components';
import { Main as MainLayout, Minimal as MinimalLayout} from './layouts';

import {
  Dashboard as DashboardView,
  ProductList as ProductListView,
  UserList as UserListView,
  Typography as TypographyView,
  Icons as IconsView,
  Account as AccountView,
  Settings as SettingsView,
  NotFound as NotFoundView,
  Login as LoginView,
} from './views';

const Routes = () => {
  const authed = !!localStorage.getItem('token');
  //const authed = true;

  return (
    <Switch>
      <RouteWithLayout authed={authed} component={LoginView} exact layout={MinimalLayout} path="/login" />
      <Redirect exact from="/" to="/login" />
      {/*authed={this.state.authed}*/}
      <RouteWithLayout authed={authed} component={DashboardView} exact layout={MainLayout} path="/dashboard" />{' '}
      <RouteWithLayout authed={authed} component={UserListView} exact layout={MainLayout} path="/users" />
      <RouteWithLayout authed={authed} component={ProductListView} exact layout={MainLayout} path="/products" />
      <RouteWithLayout authed={authed} component={TypographyView} exact layout={MainLayout} path="/typography" />
      <RouteWithLayout authed={authed} component={IconsView} exact layout={MainLayout} path="/icons" />
      <RouteWithLayout authed={authed} component={AccountView} exact layout={MainLayout} path="/account" />
      <RouteWithLayout authed={authed} component={SettingsView} exact layout={MainLayout} path="/settings" />
      <RouteWithLayout authed={authed} component={NotFoundView} exact layout={MinimalLayout} path="/not-found" />
      <Redirect to="/not-found" />
    </Switch>
  );
};

export default Routes;

А мой RouteWithLayout выглядит так:

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';

const RouteWithLayout = props => {
  const { authed, layout: Layout, component: Component, ...rest } = props;

  return (
    <Route
      {...rest}
      render={matchProps =>
        authed === true ? (
          <Layout>
            <Component {...matchProps} />
          </Layout>
        ) : (
          <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )
      }
    />
  );
};

RouteWithLayout.propTypes = {
  authed: PropTypes.any,
  component: PropTypes.any.isRequired,
  layout: PropTypes.any.isRequired,
  path: PropTypes.string,
  props: PropTypes.any.isRequired,
};

export default RouteWithLayout;

1 Ответ

3 голосов
/ 29 января 2020

Похоже, если auth === false, вы будете бесконечно перенаправлять, потому что маршрут /login использует RouteWithLayout.

Учитывая auth === false:

  1. Перейдите к / login
  2. RouteWithLayout logi c используется
  3. Если аутентификация неверна, перенаправить на / login

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

Примечание: у вас есть пауза {' '} после маршрута вашей панели мониторинга.

Еще одно примечание: вы ' Возможно, мы до сих пор работаем над этой частью, но стоит упомянуть, что это ОЧЕНЬ небезопасно: const authed = !!localStorage.getItem('token'); Этот код означает, что любое не ложное значение будет принято в качестве действительного токена, то есть я мог бы вручную добавить фиктивный токен в localStorage и выполнить аутентификацию.

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