我尝试使用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
的箭头功能无法正常工作?
答案 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
,但这是不好的做法,因为它经常会导致混淆。