← 返回目录

第9课: HTTP请求

Axios与数据获取详解

课程简介

本课程将深入讲解React中HTTP请求的核心概念和实践技巧。通过学习本课程,你将掌握如何在React应用中进行数据获取、处理异步请求、管理请求状态以及处理错误,为构建完整的React应用打下坚实基础。

核心知识点

1. HTTP请求的基本原理

2. 使用fetch API进行请求

// 使用fetch API进行GET请求
import React, { useState, useEffect } from 'react';

function FetchExample() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    // GET请求
    fetch('https://jsonplaceholder.typicode.com/posts/1')
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP错误! 状态: ${response.status}`);
        }
        return response.json();
      })
      .then(data => {
        setData(data);
        setLoading(false);
      })
      .catch(error => {
        setError(error.message);
        setLoading(false);
      });
  }, []);
  
  // POST请求示例
  const handlePost = () => {
    fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        title: '新文章',
        body: '这是文章内容',
        userId: 1,
      }),
    })
      .then(response => response.json())
      .then(data => {
        console.log('POST响应:', data);
      });
  };
  
  if (loading) return 
加载中...
; if (error) return
错误: {error}
; return (

Fetch API示例

{data && (

{data.title}

{data.body}

)}
); } export default FetchExample;

3. 使用Axios库进行请求

// 使用Axios进行HTTP请求
import React, { useState, useEffect } from 'react';
import axios from 'axios';

function AxiosExample() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    // GET请求
    axios.get('https://jsonplaceholder.typicode.com/posts/1')
      .then(response => {
        setData(response.data);
        setLoading(false);
      })
      .catch(error => {
        setError(error.message);
        setLoading(false);
      });
  }, []);
  
  // POST请求示例
  const handlePost = () => {
    axios.post('https://jsonplaceholder.typicode.com/posts', {
      title: '新文章',
      body: '这是文章内容',
      userId: 1,
    })
      .then(response => {
        console.log('POST响应:', response.data);
      });
  };
  
  // 错误处理示例
  const handleError = () => {
    axios.get('https://jsonplaceholder.typicode.com/non-existent-endpoint')
      .then(response => {
        console.log('响应:', response.data);
      })
      .catch(error => {
        if (error.response) {
          // 服务器返回错误状态码
          console.log('响应错误:', error.response.data);
          console.log('状态码:', error.response.status);
        } else if (error.request) {
          // 请求已发送但没有收到响应
          console.log('请求错误:', error.request);
        } else {
          // 其他错误
          console.log('错误:', error.message);
        }
      });
  };
  
  if (loading) return 
加载中...
; if (error) return
错误: {error}
; return (

Axios示例

{data && (

{data.title}

{data.body}

)}
); } export default AxiosExample;

4. 配置Axios实例

// 配置Axios实例
import axios from 'axios';

// 创建自定义Axios实例
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
});

// 请求拦截器
api.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

// 响应拦截器
api.interceptors.response.use(
  response => {
    // 对响应数据做点什么
    return response;
  },
  error => {
    // 处理响应错误
    if (error.response && error.response.status === 401) {
      // 未授权,跳转到登录页
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

// 使用实例发送请求
export const fetchPosts = () => api.get('/posts');
export const createPost = (data) => api.post('/posts', data);
export const updatePost = (id, data) => api.put(`/posts/${id}`, data);
export const deletePost = (id) => api.delete(`/posts/${id}`);

export default api;

5. 管理请求状态和副作用

// 管理请求状态和副作用
import React, { useState, useEffect, useCallback } from 'react';
import { fetchPosts } from './api';

function DataFetchingExample() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [page, setPage] = useState(1);
  
  // 使用useCallback记忆获取数据的函数
  const loadPosts = useCallback(async () => {
    setLoading(true);
    setError(null);
    
    try {
      const response = await fetchPosts(page);
      setPosts(prevPosts => 
        page === 1 ? response.data : [...prevPosts, ...response.data]
      );
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [page]);
  
  // 初始加载和页码变化时获取数据
  useEffect(() => {
    loadPosts();
  }, [loadPosts]);
  
  // 清理函数 - 取消请求
  useEffect(() => {
    let isMounted = true;
    
    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetchPosts(page);
        if (isMounted) {
          setPosts(response.data);
        }
      } catch (err) {
        if (isMounted) {
          setError(err.message);
        }
      } finally {
        if (isMounted) {
          setLoading(false);
        }
      }
    };
    
    fetchData();
    
    return () => {
      isMounted = false;
    };
  }, [page]);
  
  return (
    

数据获取示例

{error &&
{error}
} {loading &&
加载中...
}
{posts.map(post => (

{post.title}

{post.body}

))}
第 {page} 页
); } export default DataFetchingExample;

6. 最佳实践和性能优化

最佳实践:
注意事项:

实践练习

练习任务:
  1. 基础练习:

    创建一个使用fetch API获取数据的组件,显示用户列表,并处理加载状态和错误。

  2. 中级练习:

    使用Axios实现一个完整的CRUD操作,包括创建、读取、更新和删除帖子,并添加分页功能。

  3. 高级练习:

    创建一个自定义Hook封装数据获取逻辑,支持缓存、重试和取消请求功能,并在实际应用中使用。

  4. 综合练习:

    构建一个完整的React应用,集成Axios进行数据获取,实现用户认证、数据展示和表单提交功能。

fetch API vs Axios对比

特性 fetch API Axios
浏览器支持 现代浏览器原生支持 所有浏览器(需要polyfill)
请求拦截 不支持 支持
响应拦截 不支持 支持
自动转换JSON 不支持(需要手动调用response.json()) 支持
错误处理 只在网络错误时 reject 根据状态码 reject
取消请求 支持(AbortController) 支持(CancelToken)
超时设置 支持(AbortController) 支持
进度监控 支持(ReadableStream) 支持

总结

通过本课程学习,你应该掌握了React中HTTP请求的核心知识和实践技巧:

HTTP请求是现代前端应用的核心功能之一,掌握好这部分知识,你将能够构建更加完整、健壮的React应用。继续深入学习和实践,不断提升你的React开发能力。