【问题标题】:Failed prop type: The prop `location` is marked as required in `PrivateRoute`, but its value is `undefined`失败的道具类型:道具`location`在`PrivateRoute`中标记为必填,但其值为`undefined`
【发布时间】:2022-01-05 03:19:30
【问题描述】:

为了只允许经过身份验证的用户访问,我创建了一个组件 PrivateRoute,如 here 所述。一切正常,但它给了我一个警告,“位置”未定义。

import React from 'react';
import PropTypes from 'prop-types';
import { Redirect, Route } from 'react-router-dom';
import auth from '../../hooks/login/auth';

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={(props) => (
      auth.getToken() !== null ? (
        <Component {...props} />
      ) : (
        <Redirect to={{
          pathname: '/log_in',
          state: { from: props.location },
        }}
        />
      )
    )}
  />
);

PrivateRoute.propTypes = {
  component: PropTypes.any.isRequired, // eslint-disable-line
  location: PropTypes.shape({
    pathname: PropTypes.string.isRequired,
  }).isRequired,
};

export default PrivateRoute;
<Switch>
   <Route exact path="/" component={LogIn} />
   <Route exact path="/log_in" component={LogIn} />
   <PrivateRoute exact path="/dashboard" component={Dashboard} />
</Switch>

如果我在渲染方法中创建控制台日志,则始终定义位置。怎么回事?

<Route
    {...rest}
    render={(props) => {
      console.log('LOCATION', props.location);
      return auth.getToken() !== null ? (
        <Component {...props} />
      ) : (
        <Redirect to={{
          pathname: '/log_in',
          state: { from: props.location },
        }}
        />
      );
    }}
  />

我试图给 location 一个默认值,但是整个页面都是空白的。

PrivateRoute.propTypes = {
  component: PropTypes.any.isRequired, // eslint-disable-line
  location: PropTypes.shape({
    pathname: PropTypes.string.isRequired,
  }),
};

PrivateRoute.defaultProps = {
   location: {
    pathname: '',
   },
};

这里有什么问题?当任何控制台日志输出显示已定义的位置对象时,位置如何可能未定义?

【问题讨论】:

    标签: javascript reactjs react-router react-router-dom react-proptypes


    【解决方案1】:

    问题

    您正在为PrivateRoute 组件声明一个location PropType,这显然是未定义的,因为您在渲染时没有将location 属性传递给您的PrivateRoute 组件,并且您正在记录@987654321 PrivateRoute 正在渲染的Route 组件的@。

    const PrivateRoute = ({
      component: Component,  // <-- not logging any of these props
      ...rest
    }) => (
      <Route
        {...rest}
        render={(props) => ( // <-- logging these route props
          auth.getToken() !== null ? (
            <Component {...props} />
          ) : (
            <Redirect to={{
              pathname: '/log_in',
              state: { from: props.location },
            }}
            />
          )
        )}
      />
    );
    

    location 甚至不是 Route 组件道具,它只是传递给所有三种渲染方法(componentrenderchildren 函数)的道具之一。

    如果您想要/需要指定location.pathname 属性可用,那么这应该在您的自定义PrivateRoute 组件正在呈现的组件上完成,因为这是传递location 属性的地方。在这种情况下,Dashboard 组件应该将 location.pathname 定义为必需的属性。

    如果有帮助,您可以安装和使用 react-router-prop-types 软件包。它导出了 location PropType declarationpathname 已经需要的属性。

    export const location = PropTypes.shape({
      hash: PropTypes.string.isRequired,
      key: PropTypes.string, // only in createBrowserHistory and createMemoryHistory
      pathname: PropTypes.string.isRequired,
      search: PropTypes.string.isRequired,
      state: PropTypes.oneOfType([
        PropTypes.array,
        PropTypes.bool,
        PropTypes.number,
        PropTypes.object,
        PropTypes.string,
      ]), // only in createBrowserHistory and createMemoryHistory
    });
    

    Dashboard:

    import { location } from 'react-router-prop-types';
    
    Dashboard.propTypes = {
      // ... the other prop types
      location: location.isRequired,
    };
    

    【讨论】:

      猜你喜欢
      • 2018-01-24
      • 2019-05-21
      • 2020-01-14
      • 2019-07-15
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多