我正在一个 React 项目中工作,所以每次我注册一个新用户时,它都会创建 2 个客户 ID,它应该为每个用户创建一个。
这是我的代码:
const ConfirmEmail = ({ handleItems, onSubmitUser }) => {
let params = useParams();
let isMounted = true;
const [loading, setLoading] = useState(true);
useCallback(() => {
fetchData();
}, [isMounted]);
const fetchData = async () => {
try {
if (JSON.parse(localStorage.getItem("user"))) return;
const response = await UserService.confirmEmail(params.tokenEmail);
if (response && response.data && !response.err) {
const { user, accessToken } = response.data;
localStorage.setItem("accessToken", accessToken);
if (isMounted) {
handleItems();
onSubmitUser(user);
}
}
if (isMounted) setLoading(false);
} catch (err) {
const { response } = err;
if (response?.data?.data) toast.error(response.data.data);
}
// Unmounted
return (isMounted = false);
};
您在编写问题中的代码时可能犯了一个错误,而您实际上有:
useEffect(() => {
fetchData();
}, []);
而不是:
useCallback(() => {
fetchData();
}, [])
与第二个选项一样,您定义的回调永远不会被调用。
我怀疑你只是在开发中遇到这个问题,因为 React 调用
useEffects
以及使用 React.StrinctMode
时。无论哪种方式,您都可以使用 ref
来修复此问题,以确保只发送一个请求:
const ConfirmEmail = ({
handleItems,
onSubmitUser,
}) => {
const params = useParams();
const [loading, setLoading] = useState(true);
const confirmEmail = useCallback(() => {
try {
if (localStorage.getItem("user")) return;
const response = await UserService.confirmEmail(params.tokenEmail);
if (response && response.data) {
const { user, accessToken } = response.data;
localStorage.setItem("accessToken", accessToken);
handleItems();
onSubmitUser(user);
}
} catch (err) {
toast.error(err.message || 'Something went wrong.');
}
setLoading(false);
}, [params, handleItems, onSubmitUser])
const emailConfirmed = useRef(false)
useEffect(() => {
if (emailConfirmed.current) return;
emailConfirmed.current = true;
// This will only be called once when the component is mounted:
confirmEmail();
}, [confirmEmail]);
};