React路由器私有路由不呈现

时间:2018-03-17 12:09:01

标签: javascript reactjs react-router

我尝试使用react router v4设置受保护的路由。

我有以下内容,效果很好。

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

但是,当我将此代码更改为:

type PrivateRouteProps = {
  component: Component,
};

const PrivateRoute = ({ component, authed, ...rest }: PrivateRouteProps) => (
  <Route
    {...rest}
    render={props =>
      authed === true ? (
        <Component {...props} />
      ) : (
        <Redirect to={{ pathname: '/', state: { from: props.location } }} />
      )
    }
  />
);

我收到错误:TypeError: instance.render is not a function。当我改为(注意component: Component)时,一切正常:

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

App.js的渲染功能如下:

render() {
    return this.state.loading === true ? (
      'loading'
    ) : (
      <BrowserRouter>
        <div>
          {this.renderHeader()}
          <Switch>
            <Route exact path="/" component={LandingPage} />
            <PrivateRoute
              authed={this.state.authed}
              path="/home"
              component={HomePage}
            />
            <Route component={PageNotFoundPage} />
          </Switch>
        </div>
      </BrowserRouter>
    );
  }

为什么PrivateRouteProps的箭头功能无法正常工作?

1 个答案:

答案 0 :(得分:1)

在第二个示例中,您尝试使用

呈现传入的组件
<Button FocusVisualStyle="{x:Null}">

从您定义流量类型的方式来看,我猜您导入了<Component {...props}/> ,如下所示:

Component

这意味着 import React, {Component} from 'react'. 不会引用Component道具中传递的组件,但仍会引用从component 导入的班级Component因为你没有在功能组件内的任何地方遮挡它。即使您在第一个示例中导入react,它仍然有效,因为您使用prop Component的值隐藏了名称Component。在第二个例子中,你没有这样做。

这就是您收到错误的原因,因为反应类component既没有Component方法,也没有您期望的任何其他功能。

您需要将道具render()分配给大写的另一个名称,例如component然后渲染该变量。请注意,名称需要大写。否则它将被解释为通常的html节点而不是反应组件:

Node

您当然也可以使用type PrivateRouteProps = { component: Component, }; const PrivateRoute = ({ component: Node /* assign it to a capitalized name */, authed, ...rest }: PrivateRouteProps) => ( <Route {...rest} render={props => authed === true ? ( {/* Do not use `Component` here as it refers to the class imported from react and not to your component */} <Node {...props} /> ) : ( <Redirect to={{ pathname: '/', state: { from: props.location } }} /> ) } /> ); 作为名称,它将从外部范围隐藏名称Component,但这是不好的做法,因为它经常会导致混淆。