React Hooks Ts Axios

The React project Ts version uses the Hooks API. This example focuses on configuring Axios and writing two interfaces using Eggjs for testing.

Look at the./ SRC/API and./ SRC /model directories.

├ ─ SRC │ ├ ─ API │ │ ├ ─ API. Ts │ │ └ ─ status. The ts │ ├ ─ model │ │ └ ─ the login. The tsCopy the code

./src/api/api.ts

import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios';
import qs from 'qs'

import { showMessage } from "./status";
import { message, Spin } from 'antd';
import { ILogin, IUser } from 'model/login';


// Return the interface of res.data
export interface IResponse {
  code: number | string;
  data: any;
  msg: string;
}

let axiosInstance:AxiosInstance = axios.create({
  baseURL: process.env.REACT_APP_BASE_URL,
  headers: {
    Accept: "application/json"."Content-Type": "application/x-www-form-urlencoded"
  },
  transformRequest: [
    function(data) {
      // Use form-data to transmit data
      delete data.Authorization;
      data = qs.stringify(data);
      returndata; }}]);// The Axios instance intercepts the response
axiosInstance.interceptors.response.use(
  (response: AxiosResponse) = > {
    if (response.headers.authorization) {
      localStorage.setItem('app_token', response.headers.authorization);
    } else {
      if (response.data && response.data.token) {
        localStorage.setItem('app_token', response.data.token); }}if (response.status === 200) {
      return response;
    } else {
      showMessage(response.status);
      returnresponse; }},// The request failed
  (error: any) = > {
    const {response} = error;
    if (response) {
      // The request has been sent, but it is not in the scope of 2xx
      showMessage(response.status);
      return Promise.reject(response.data);
    } else {
      message.error(The network connection is abnormal, please try again later! '); }});// The Axios instance intercepts the request
axiosInstance.interceptors.request.use(
  (config: AxiosRequestConfig) = > {
    const token = localStorage.getItem('app_token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config;
  },
  (error:any) = > {
    return Promise.reject(error); })/ * * *@description: User login *@params {ILogin} params
 * @return {Promise}* /
export const Login = (params: ILogin): Promise<IResponse> => {
  return axiosInstance.post('user/login',params).then(res= > res.data);
};

/ * * *@description: Obtains the user * by id@params {IUser} params
 * @return {Promise}* /
export const getUserInfo = (params: IUser): Promise<IResponse> => {
  return axiosInstance.post('user/getInfo',params).then(res= > res.data);
};
Copy the code
  • This file creates an Axios instance and processes it by adding request and response interceptors to the instance.
  • Create axios.create transformRequest configuration, delete Authorization parameter first, The qs (NPM install @types/qs) dependencies convert the parameter Form (convert object literals to Form Data format).
  • The token is processed in response interception
  • In request interception, add a token to Authorization in the request header. The value can be modified according to specific service requirements.
  • This file creates a login interface login and get user information interface getUserInfo to test the interface provided by EggJS.
  • For uniform processing, all requests use POST mode

./src/api/status.ts

export const showMessage = (status:number|string) : string= > {
  let message:string = "";
  switch (status) {
    case 400:
      message = "Request error (400)";
      break;
    case 401:
      message = "Unauthorized, please log in to (401) again";
      break;
    case 403:
      message = "Access denied (403)";
      break;
    case 404:
      message = "Request error (404)";
      break;
    case 408:
      message = "Request timeout (408)";
      break;
    case 500:
      message = "Server error (500)";
      break;
    case 501:
      message = "Service not implemented (501)";
      break;
    case 502:
      message = Network error (502);
      break;
    case 503:
      message = "Service unavailable (503)";
      break;
    case 504:
      message = "Network timeout (504)";
      break;
    case 505:
      message = "HTTP version not supported (505)";
      break;
    default:
      message = 'Connection error (${status})! `;
  }
  return `${message}, please check the network or contact the administrator! `;
};
Copy the code
  • Status. ts Returns the message text corresponding to the status.

./src/model/login.ts

export interface ILogin {
  username: string;
  password: string;
}

export const createEmptyLogin = (): ILogin= > ({
  username: "".password: ""
});

export interface IUser {
  userId: string;
}
Copy the code
  • Here, we define interfaces related to various interfaces in a centralized manner.

Test the logon interface, listing only the main logic:

.import { ILogin } from "model/login";
import { IResponse, Login } from 'api/api';
import { Button, message } from 'antd'; .export default () => {
  ...
  // Logon button logic
  const handleLogin = async (login:ILogin) => {
    // Call the login Api to get the results
    let res:IResponse = await Login(login);
    // Process the result
    if( res.code === 200) {if(res.data.user_id){
        localStorage.setItem('user_id', res.data.user_id);
      }
      // A message is displayed indicating login success
      message.success(res.msg);
    }else{
      // A login failure message is displayedmessage.error(res.msg); }}; .return (
    <>
      <Button 
        type="ghost" 
        onClick={()= >HandleLogin ({the username: 'admin' password: '123456'})} ></Button>
    </>)}Copy the code

Write a logon interface with eggJS. The returned JSON structure looks like this.

{
  "code":200."msg":"Login successful"."data": {"user_id": "57c4dda0b42521e3994aa5196ae79485"."token": "1 yjhbgcioijiuzi1niisinr5cci6ikpxvcj9. 2 yj1c2vybmftzsi6innvbmljiiwiawfwijoxnje5ndkxmzizfq uIlcV - hO2FZgskyBorMfoUi2tN69MU5 1XXEbtMN2BZQ"}}Copy the code
  • After successful login, the user_id is saved to the local storage.
  • The login interface request header does not contain authorization. After successful login, the token is stored in the local storage./ SRC/API/API.

Now look at the interface that gets user information.

import React,{ useState, useEffect } from "react";
import { Button } from 'antd';
import { IResponse, getUserInfo } from 'api/api';
import { IUser } from "model/login";
export default() = > {const [user, setUser] = useState<IUser>({ userId: String(localStorage.getItem('user_id')) || "" });
  const [userInfo, setUserInfo] = useState<any> (null);

  // Obtain user information
  const showUserInfo = async (user:IUser) => {
  	let res = await getUserInfo(user);
  	console.log(res);
  	setUserInfo(res.data);
  }

  // Execute after the component is loaded
  useEffect(() = >{
    // Call the interface to get user information
  	showUserInfo(user);
  },[]);

  return(
  	<>
  	  <Button 
	    style={{'width':'200px'}}
	    type="primary" 
	    onClick={()= >ShowUserInfo (user)} > Obtains user information</Button>
	  <p>{JSON.stringify(userInfo)}</p>
  	</>)}Copy the code
  • UseEffect is used as the componentDidMount lifecycle, where the logic is that the page defaults to calling the get user information interface.
  • The interface can also be invoked once by clicking the button.

Json structure returned by getting user information

{
  "code":200."msg":"User information obtained successfully"."data": {"user_id": "57c4dda0b42521e3994aa5196ae79485"."name": "admin"."real_name": "1"."user_role":2."headimg": null."login_time": 1564994793122,}}Copy the code

The last time

  • For env configuration, unlike Vue, VUE_APP_BASE_URL is changed to REACT_APP_BASE_URL
  • Test the interface reference to the previous article “Configuring AXIOS for VUe3.0 TS Project”