在react中,我有一个私有路由组件,该组件具有一个isAuthenticated
状态值,该状态值用于呈现正在包装的组件,或重定向回我的登录页面。
为了检测刷新并执行身份验证检查,我添加了一个useEffect
钩子,希望可以检查身份验证状态,然后更新isAuthenticated
,然后返回组件或重定向
const PrivateRoute: React.FC<IPrivateRouteProps> = (props) => {
const dispatch = useDispatch();
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
useEffect(() => {
authService.getIdentity().then(response => {
if (response) {
dispatch(signIn(new Identity(response.account)));
setIsAuthenticated(true);
} else {
setIsAuthenticated(false);
}
});
}, [])
return isAuthenticated ? (
<Route {...props} component={props.component} render={undefined} />
) : (
<Redirect to={{ pathname: props.redirectPath }} />
);
};
不幸的是,这不起作用,我不确定为什么或如何解决它。
isAuthenticated
的值在渲染时始终为false,并且在控制台中出现以下错误...。
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in PrivateRoute (at App.tsx:23)
我可以确认它确实流向setIsAuthenticated(true)
,但是在渲染之前,这从未反映在isAuthenticated
的值中。
我如何/应该解决这个问题?
谢谢
答案 0 :(得分:1)
我认为问题在于代码第一次运行时,它使用isAuthenticated false评估渲染,然后使用useEffect并尝试更新值,但是您已经被重定向到另一个页面。
我建议使用另一个变量来了解身份验证是否已通过,并且仅在身份验证完成后才能继续。
const PrivateRoute: React.FC<IPrivateRouteProps> = (props) => {
const dispatch = useDispatch();
const [loading, setLoading] = React.useState(true);
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
useEffect(() => {
authService.getIdentity().then(response => {
if (response) {
dispatch(signIn(new Identity(response.account)));
setIsAuthenticated(true);
} else {
setIsAuthenticated(false);
}
setLoading(false);
});
}, [])
if (isLoading) {
//we are not ready yet
return null;
}
return isAuthenticated ? (
<Route {...props} component={props.component} render={undefined} />
) : (
<Redirect to={{ pathname: props.redirectPath }} />
);
};
答案 1 :(得分:0)
如您所见,它显示为Can't perform a React state update on an unmounted component.
。
为防止出现此问题,您能否尝试像这样将<Route>
和<Redirect>
放在<React.Fragment>
内?
return isAuthenticated ? (
<React.Fragment>
<Route {...props} component={props.component} render={undefined} />
</React.Fragment>
) : (
<React.Fragment>
<Redirect to={{ pathname: props.redirectPath }} />
</React.Fragment>
);