为何React项目中会出现‘Property 'data' does not exist on type 'void'’错误?
解决React Query中useMutation的mutate返回void类型错误
错误信息
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);'
问题原因
React Query的mutate函数不返回Promise,它仅异步触发请求但不支持await语法,因此你用const response = await UserLogin(...)得到的response是void类型,自然不存在data属性。
解决方案
方案1:使用mutateAsync替代mutate
mutateAsync是mutate的Promise版本,支持用await直接获取请求返回值,修改代码如下:
// 替换原有的mutate为mutateAsync const { mutateAsync: UserLogin } = useMutation({ mutationFn: getLoginData, }); // handleLogin逻辑保持不变,因为mutateAsync返回Promise 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("登录错误:无响应数据"); } } catch (error) { console.error("登录错误:", error); } } };
方案2:通过onSuccess回调处理结果
把token存储逻辑移到useMutation的onSuccess回调中,这是React Query推荐的异步操作处理方式:
const { mutate: UserLogin } = useMutation({ mutationFn: getLoginData, onSuccess: (response) => { 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("登录错误:无响应数据"); } }, onError: (error) => { console.error("登录错误:", error); } }); // 修改handleLogin,直接调用mutate即可 const handleLogin = (e: React.FormEvent) => { e.preventDefault(); if (checkUserValidation()) { UserLogin({ email: loginData.email, password: loginData.password, }); } };
额外修复:请求格式问题
你的getLoginData函数存在矛盾:使用FormData但设置了Content-Type: application/json,会导致后端无法正确解析请求。根据后端要求二选一:
如果后端接收JSON格式
export const getLoginData = async (loginData: LoginData) => { try { return await axiosClient.post("/auth/authenticate", loginData, { headers:{ // axios会自动设置Content-Type为application/json,无需手动指定 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, }); } catch (error) { console.error("API错误:", error); throw error; } };
如果后端接收FormData格式
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:{ // axios会自动设置Content-Type为multipart/form-data,无需手动指定 'Authorization': `Bearer ${localStorage.getItem('accessToken')}` }, }); } catch (error) { console.error("API错误:", error); throw error; } };
内容的提问来源于stack exchange,提问作者mikasa akerman
相关产品推荐
相关产品推荐

