为什么会出现“类型‘void’上不存在属性‘数据’”错误?

问题描述 投票:0回答:1

我创建了一个 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;
  }
};
typescript axios jwt react-query
1个回答
0
投票

您需要告诉

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
字段。

© www.soinside.com 2019 - 2024. All rights reserved.