我正在使用React、Express和Axios创建一个带有令牌参数的验证页面
下面是页面脚本:
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';
import { Typography } from '@mui/material';
const VerifyPage = () => {
const { token } = useParams();
const [verificationResult, setVerificationResult] = useState<any>(null);
useEffect(() => {
const verifyEmail = async () => {
try {
if (verificationResult) return;
const res = await axios.get(`http://localhost:5000/api/auth/verify/${token}`);
console.log(res.data.message);
if (res && res.data) {
setVerificationResult(res.data.message);
} else {
setVerificationResult('Something went wrong');
throw new Error('Something went wrong');
}
return;
} catch (error: any) {
setVerificationResult(error.message);
return;
}
};
verifyEmail();
}, [token]);
return (
<div id='VerifyPage'>
{verificationResult ? (
<Typography variant='h1' align='center' sx={{ mt: 30, fontFamily: 'Noto Sans', color: 'white' }}>
<strong>{verificationResult}</strong>
</Typography>
) : (
<Typography variant='h1' align='center' sx={{ mt: 30, fontFamily: 'Noto Sans', color: 'white' }}>
<strong>Verifying...</strong>
</Typography>
)}
</div>
);
};
export default VerifyPage;
下面是API
const verifyEmail = async (verificationToken: string) => {
try {
const user = await User.findOne({ verificationToken });
if (!user) {
return 'Invalid token';
}
if (user.verified) {
return 'Email already verified';
}
await User.updateOne({ verificationToken }, { verified: true });
return 'Email verified';
} catch (err) {
console.log(err);
return 'Server error';
}
};
app.get('/api/auth/verify/:verificationToken', async (req: Request, res: Response) => {
const { verificationToken } = req.params;
const message = await verifyEmail(verificationToken);
res.send({ message: message });
});
用户收到一封包含链接和令牌的电子邮件。当我打开验证页面时,useEffect向服务器发送多个axios请求。这导致始终显示“Email already verified”(因为它验证了它,然后尝试再次验证)。
我试过使用条件,比如if (verificationResult) return;
或者甚至创建新的状态变量,const [verified, setVerified] = useState<boolean>(false);
和if (verified) return;
但什么都没变
为什么会这样?我做错了什么?:)
编辑1我尝试使用
if (verificationResult !== null) return;
但什么都没改变我也试着
console.log('UseEffect ran');
console.log(verificationResult);
每次运行时,它似乎都保持为null。我相信这是因为verifyEmail函数是异步的。似乎当状态为null时,useEffect会运行多次,直到它从服务器获得响应(最后2)。我如何修复这种不受控制的useEffect调用(也许让它等待直到它从服务器获得响应)?顺便说一句,谢谢你的帮助〈3
2条答案
按热度按时间blmhpbnm1#
找到问题了!经过研究,我发现这种情况只发生在开发模式下。这是因为从React 18开始,useEffect被调用了两次,即使它有空的依赖数组。我通过从index.ts中删除****来修复这个问题<React.StrictMode>
更多信息:React Hooks: useEffect() is called twice even if an empty array is used as an argument
mwg9r5ms2#
你是正确的亚历克斯,这发生在我身上在我以前的项目.如果你检查以下链接:React docs - Strict Mode,你会看到它特别提到:
最佳实践是添加一个标志,以便仅在组件完全呈现时才运行API调用:
1.用于更新布尔值的附加useEffect
1.检查布尔值以触发API调用