我正在创建一个使用AWS身份验证的小型应用程序(它提供了社交和非社交登录的便捷处理)。在 AWS 的重定向流程中,我订阅了 useEffect 内的登录事件,并通过 POST 创建用户到我的服务器。
不幸的是,useEffect 运行了两次(我在那里放了一个日志来确认)。另一篇 SO 帖子建议 useEffect 应该是纯粹的,并且
到目前为止我的代码:
export default function LoginRedirect() {
const _userService = new UserService();
const navigator = useNavigate();
useEffect(() => {
console.log("activating useEffect in LoginRedirect");
const getUserAndProcess = async (eventCancelToken: () => void) => {
try {
console.log("processing user...");
const currentUser = await Auth.currentAuthenticatedUser() as CognitoUser
if(currentUser != null) eventCancelToken() //stop listening to any more auth events
else return;
const userSession = currentUser.getSignInUserSession();
const idToken = userSession?.getIdToken().getJwtToken();
const accessToken = userSession?.getAccessToken().getJwtToken();
const refreshToken = userSession?.getRefreshToken().getToken();
if(idToken === undefined || accessToken === undefined || refreshToken === undefined) {
throw new Error("idToken, accessToken, or refreshToken is undefined");
}
const processUserResult = await _userService.processUser(
{
IdToken: idToken
} as ProcessUser
);
console.log(currentUser);
console.log(processUserResult);
navigator("/");
} catch(error) {
console.warn(error);
}
};
const authListenerCancelToken = Hub.listen("auth", ({ payload: { event, data }}) => {
switch (event) {
case 'signIn':
console.log('Sign in happened!', data);
getUserAndProcess(authListenerCancelToken)
.catch(console.error);
break;
case 'cognitoHostedUI':
console.log('Sign in happened via cognito hosted UI!', data);
break;
case "signOut":
break;
case 'signIn_failure':
case 'cognitoHostedUI_failure':
console.log('Sign in failure', data);
break;
}
});
getUserAndProcess(authListenerCancelToken).catch(console.error);
});
return (
<div className="h-screen w-full grid place-items-center">
<div className="grid place-items-center">
<h1 className="text-lg my-3">Logging you in...</h1>
<div className="loading loading-ring loading-lg justify-self-center"></div>
</div>
</div>
);
}
你可以检查 useEffect 的第二个参数作为空白数组,这样一旦页面加载它就会被调用
useEffect(() => { }, []);