关于javascript:对私有路由进行无限渲染-获取错误错误:已超过最大更新深度

React private Route infinite render - Getting error Error: Maximum update depth exceeded

如果用户已通过身份验证,我将尝试在私有路由中呈现我的组件。但是我一直在得到错误。
错误:已超过最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。 React限制了嵌套更新的数量,以防止无限循环。

要查看用户是否已通过身份验证,请从localStorage获取令牌。

注释行const authed = true用于测试目的,并且有效。

"我的路线"组件如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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;

如果auth === false,您将无限重定向,因为/login路由使用RouteWithLayout

给出auth === false

  • 导航到/ login
  • 使用RouteWithLayout逻辑
  • 如果auth不正确,请重定向到/ login
  • 这些步骤会一遍又一遍地重复,因此您需要特殊的登录路径-许多不同的实现方式。

    旁注:仪表板路线后有一个流浪{' '}

    另一点说明:您可能仍在研究此部分,但值得一提的是,这是非常不安全的:const authed = !!localStorage.getItem('token');该代码表示??任何非虚假的值都将被视为有效令牌,这意味着我可以手动将一个虚拟令牌添加到localStorage并进行身份验证。