我正在尝试创建用于身份验证的受保护路由。我有一个在文档中建议的ProtectedRoute组件,如下所示:
interface ProtectedRouteProps {
auth: AuthState;
}
const ProtectedRoute = ({
children,
auth,
...rest
}: RouteProps & ProtectedRouteProps): JSX.Element => {
console.log(auth)
return (
<Route
{...rest}
render={(props: RouteProps) =>
auth.isAuthenticated ? children : <Redirect to={{pathname: "/signin", state: "Please sign in" }} />
}
/>
);
};
export default ProtectedRoute;
然后我使用它,如果有人被重定向到登录页面,我想显示状态(“请登录”)。
我有一个处理路由的包装器组件:
export interface IWrapper {
auth: AuthState
}
class Wrapper extends Component<IWrapper> {
constructor(props: IWrapper){
super(props);
console.log(props)
}
render() {
return (
<div>
<BrowserRouter>
<HeaderContainer />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route exact path="/signup">
<SignUpView />
</Route>
<ProtectedRoute auth={this.props.auth} path="/dashboard">
<DashboardContainer />
</ProtectedRoute>
</Switch>
<Route exact path="/" component={Home}></Route>
<Route exact path="/signout" component={SignUpView}></Route>
<Route exact path="/signin" component={SignIn}></Route>
</BrowserRouter>
</div>
);
}
}
const mapStateToProps = (state: AppState) => ({
auth: state.auth
})
export default connect(mapStateToProps)(Wrapper)
这是我的登录页面:
export default class SignIn<RouteComponentProps> extends Component {
constructor(props: RouteComponentProps){
super(props);
console.log(props);
}
render() {
return (
<div>
{this.props.location.state ? (
<h2>You were redirected</h2>
) : ("")}
<SignInForm />
</div>
)
}
}
打字稿编译器说我无法执行props.location,因为“属性'location'在'Readonly <{}>和Readonly <{children ?: ReactNode;}>'类型上不存在”。
我真的不明白这意味着什么。在RouteComponentProps的类型定义中,您具有:
export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
history: H.History;
location: H.Location<S>;
match: match<Params>;
staticContext?: C;
}
那是什么问题?我已经尝试过使用重定向道具,但这也不起作用。我是Typescript的n00b,所以如果有人可以帮助我将不胜感激。谢谢。
答案 0 :(得分:3)
在没有阅读所有代码的情况下,我猜测您可以仅更改SignIn
类的定义
export default class SignIn<RouteComponentProps> extends Component { ... }
到
export default class SignIn extends Component<RouteComponentProps> { ... }
,那么您应该很好。
通常,泛型类型的参数会在类名后加上注释,在您的情况下则不需要。在extends
子句具体中,为要扩展的组件设置参数。如果您只写extends Component
而未通过Component<RouteComponentProps>
指定道具类型,则使用{}
的默认类型Component
,TS无法找到location
属性在普通对象文字{}
上。
有关泛型类的更多信息,请参见here。