我创建了一个 Post 函数来发布登录表单的电子邮件和密码数据。这里的问题是,当我尝试从响应数据访问
refresh_token
和 access_token
时,会发生以下错误:
'
ERROR in src/pages/login/index.tsx:63:22
TS2339: Property 'data' does not exist on type 'void'.
61 | password: loginData.password,
62 | });
> 63 | if (response.data){
| ^^^^
64 | const accessToken = response.data.access_token;
65 | const refreshToken = response.data.refresh_token;
66 | localStorage.setItem("accessToken", accessToken);'
而且它不仅发生在
reponse.data
,还发生在response.data.access_token
和response.data.refresh_token
。
这是代码: 这是登录组件:
import React, { useState } from 'react';
import { getLoginData } from '../../services/auth';
import { useMutation } from '@tanstack/react-query';
import { axiosClient } from '../../services/axiosInstance';
const Login = () => {
const [loginData, setLoginData] = useState({ email:'', password:''});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setLoginData({ ...loginData, [name]: value });
if (name === "email") {
setEmailMessage('');
} else if (name === "password") {
setPasswordMessage('');
}
};
const { mutate: UserLogin } = useMutation({
mutationFn: getLoginData,
onSuccess: (data) => {
console.log(data);
},
});
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
if (checkUserValidation()) {
try {
const response = await UserLogin({
email: loginData.email,
password: loginData.password,
});
if (response.data){
const accessToken = response.data.access_token;
const refreshToken = response.data.refresh_token;
localStorage.setItem("accessToken", accessToken);
localStorage.setItem("refreshToken", refreshToken);
setInterval(refreshAccessToken, 60000);
} else {
console.error("Login error: No response data");
}
} catch (error) {
console.error("Login error:", error);
}
}
};
const refreshAccessToken = async () => {
try {
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) {
console.error('Refresh token not found');
return;
}
const response = await axiosClient.post('/auth/refresh', { refreshToken });
const newAccessToken = response.data.accessToken;
localStorage.setItem('accessToken', newAccessToken);
} catch (error) {
console.error('Refresh token error:', error);
}
};
return (
<div className='grid grid-cols-2'>
<div className="mt-10 sm:mx-auto sm:w-3/4">
<form className="space-y-6" onSubmit={handleLogin}>
<div>
<label htmlFor="email" className="block text-md font-medium leading-6 text-gray-900">عنوان البريد الإلكتروني</label>
<div className="mt-4">
<input name="email" type="" className="block w-full rounded-md border-0 py-2 pr-2 text-gray-900 shadow-md ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-lime-700 sm:text-sm sm:leading-6"
onChange={handleChange}
/>
</div>
<p className='text-red-600 text-sm mt-1'>{emailMessage}</p>
</div>
<div>
<div className="flex items-center justify-between">
<label htmlFor="password" className="block text-md font-medium leading-6 text-gray-900">كلمة المرور</label>
<div className="text-sm">
<a href="#" className="font-semibold text-emerald-800 hover:text-emerald-600">هل نسيت كلمة المرور؟</a>
</div>
</div>
<div className="mt-4">
<input name="password" type="password" autoComplete="current-password" className="block w-full rounded-md border-0 py-2 pr-2 text-gray-900 shadow-md ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-lime-700 sm:text-sm sm:leading-6"
onChange={handleChange}
/>
<p className='text-red-600 text-sm mt-1'>{passwordMessage}</p>
</div>
</div>
<div className='mt-3'>
<button type="submit" className="flex w-full justify-center rounded-md bg-emerald-900 px-3 py-2 text-md font-semibold leading-6 text-white shadow-sm hover:bg-emerald-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-lime-600"
>تسجيل الدخول</button>
</div>
</form>
</div>
</div>
);
};
导出默认登录;
这是 getLoginData 函数:
import { axiosClient } from "./axiosInstance";
export type LoginData = {
email: string;
password: string;
};
export const getLoginData = async (loginData: LoginData) => {
try {
const loginDatas = new FormData();
loginDatas.append("email", loginData.email);
loginDatas.append("password", loginData.password);
return await axiosClient.post("/auth/authenticate", loginDatas,
{
headers:{
'Content-Type':'application/json',
'Authorization': `Bearer ${localStorage.getItem('accessToken')}`
},
}
);
} catch (error) {
console.error("API error:", error);
throw error;
}
};
您需要告诉
axiosClient
/auth/authenticate
返回的响应的形状
return await axiosClient.post<{ access_token:string, refresh_token: string }>(
"/auth/authenticate",
loginDatas,
{
headers:{
'Content-Type':'application/json',
'Authorization': `Bearer ${localStorage.getItem('accessToken')}`,
},
},
);
否则它默认为
void
,因此 TypeScript 将不知道 access_token
上的 refresh_token
和 response.data
字段。