教程 axios tutorial

在 React 中集成 Axios

Axios 在 React 项目中非常常见,用于与后端 API 通信。通过合理封装,可以让代码结构更清晰、可维护性更高。

一、安装 Axios

在 React 项目中安装 Axios:

bash
npm install axios
# 或
yarn add axios

`

二、基础用法示例

在组件中直接发起请求:

jsx
import React, { useEffect, useState } from "react";
import axios from "axios";

export default function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    axios.get("/api/users").then((res) => {
      setUsers(res.data);
    });
  }, []);

  return (
    <ul>
      {users.map((u) => (
        <li key={u.id}>{u.name}</li>
      ))}
    </ul>
  );
}

📘 建议使用 useEffect 控制请求生命周期,防止组件卸载时内存泄漏。

三、封装 Axios 实例

在大型项目中,推荐创建独立的 request.js:

js
// src/utils/request.js
import axios from "axios";

const request = axios.create({
  baseURL: import.meta.env.VITE_API_URL || "/api",
  timeout: 8000,
});

request.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("token");
    if (token) config.headers.Authorization = `Bearer ${token}`;
    return config;
  },
  (error) => Promise.reject(error)
);

request.interceptors.response.use(
  (res) => res.data,
  (error) => {
    console.error("API Error:", error);
    return Promise.reject(error);
  }
);

export default request;

在组件中使用:

jsx
import React, { useEffect, useState } from "react";
import request from "../utils/request";

function Posts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    request.get("/posts").then(setPosts);
  }, []);

  return (
    <div>
      <h3>文章列表</h3>
      {posts.map((p) => (
        <p key={p.id}>{p.title}</p>
      ))}
    </div>
  );
}

export default Posts;

四、使用自定义 Hook 封装请求逻辑

可以封装一个通用的 useRequest Hook:

js
import { useEffect, useState } from "react";
import request from "../utils/request";

export function useRequest(url, options = {}) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    request(url, options)
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

使用示例:

jsx
import { useRequest } from "../hooks/useRequest";

function Dashboard() {
  const { data, loading, error } = useRequest("/api/stats");

  if (loading) return <p>加载中...</p>;
  if (error) return <p>加载失败:{error.message}</p>;

  return <div>用户总数:{data.totalUsers}</div>;
}

五、与 Redux / Context 集成

在全局状态管理中,可以将 Axios 实例注入到中间件中(如 Redux Toolkit 的 thunk),统一处理请求。

js
// example using Redux Toolkit
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import request from "../utils/request";

export const fetchUsers = createAsyncThunk("users/fetch", async () => {
  return await request.get("/users");
});

const usersSlice = createSlice({
  name: "users",
  initialState: { list: [], status: "idle" },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchUsers.pending, (state) => {
        state.status = "loading";
      })
      .addCase(fetchUsers.fulfilled, (state, action) => {
        state.list = action.payload;
        state.status = "succeeded";
      });
  },
});

export default usersSlice.reducer;

六、错误提示与全局拦截

在拦截器中统一弹出错误提示(结合 Toast / Modal):

js
import { message } from "antd"; // 或其他 UI 库

request.interceptors.response.use(
  (res) => res,
  (error) => {
    message.error(error.response?.data?.message || "请求失败");
    return Promise.reject(error);
  }
);

七、总结

  • React 中推荐封装 Axios 实例,结合 Hook 管理请求状态。
  • 使用拦截器统一处理 Token 和错误。
  • 在 Redux / Context 层集成 Axios,有助于全局状态与请求同步。
  • 对于高并发场景,可结合 axios.all、AbortController 等优化性能。