我正在尝试实现一个简单的“防护”,该防护将我重定向到给定currentUser
和currentClub
值的其他组件:
export const ClubDashboard: React.FC = () => {
const { id } = useParams();
const currentUser = useStoreState(state => state.currentUser.value);
const currentClub = useStoreState(state => state.currentClub.value);
return clubGuard(
currentUser,
currentClub,
<div className="container vertical full-height-screen">
<Link to={`/clubs/${currentClub!.id}/settings`}>
<IoIosSettings className="icon absolute-top-right" />
</Link>
[...]
</div>
id);
}
这是我实现该功能的方式:
export const clubGuard = (
currentUser: User | null,
currentClub: Club | null,
page: JSX.Element,
urlClubId?: string | null,
pageLoading?: boolean
): JSX.Element => {
if (!currentUser) {
return <Redirect to={"/login"} />;
}
if (!currentClub || (currentClub && currentClub.id !== urlClubId)) {
return <Redirect to={"/"} />;
}
if (pageLoading) {
return <PageLoading />;
}
return page;
};
但是,每当currentClub
例如是null
时,它甚至都不会进入clubGuard
函数,而是直接提示错误:Uncaught TypeError: Cannot read property 'id' of null
它在进入函数之前先扫描代码,这是正常现象吗?我想念什么吗?
答案 0 :(得分:1)
这很可能是由于您要传递给函数的JSX。在传递给您的函数之前会对其进行评估(因为所有参数都是如此)。
<Link to={`/clubs/${currentClub!.id}/settings`}> // <---- This template string is most likely the culprit
<IoIosSettings className="icon absolute-top-right" />
</Link>
感叹号不进行任何空值检查,而是告诉Typescript您知道,它不能为空,并且Typescript不必担心它为空。实际上,它仍然可以为null,因为在运行时不进行任何检查。您可以阅读有关该here的更多信息。
简单的解决方案是进行空检查。
<Link to={`/clubs/${!!currentClub ? currentClub.id : 0}/settings`}>
<IoIosSettings className="icon absolute-top-right" />
</Link>