You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React自定义Hook中使用Axios获取单产品数据失败排查

问题排查与解决方案

核心问题分析

你遇到的产品名称无法显示的问题,主要由三个错误导致:

  1. 请求地址拼写错误:getSingleProduct函数中请求后缀写成了.jason,正确格式应为.json,这会导致API请求失败,singleProduct始终为null。
  2. 未使用路由参数:当前getSingleProduct硬编码请求ID为1048的产品,没有利用路由传来的id参数,无法动态获取对应产品的详情。
  3. useEffect依赖缺失:useEffect的依赖数组为空,当路由中的id变化时,不会重新触发请求;同时未将getSingleProduct加入依赖,可能导致请求逻辑不更新。

修改后的完整代码

自定义Hook:useGetProduct.js

import { useState, useCallback } from 'react';
import axios from 'axios';

const BASE_URL = "https://makeup-api.herokuapp.com/api/v1/products";

const useGetProduct = () => {
  const [products, setProducts] = useState([]);
  const [singleProduct, setSingleProduct] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
    
  const getTopProducts = useCallback(() => {
    axios.get(`${BASE_URL}.json`, {
      params: {
        product_tags: 'Canadian',
      },
    })
      .then(response => setProducts(response.data))
      .catch(err => console.error('获取热门产品失败:', err));
  }, []);

  const getSingleProduct = useCallback((productId) => {
    setLoading(true);
    setError(null);
    // 修正拼写错误,并使用传入的productId参数
    axios.get(`${BASE_URL}/${productId}.json`)
      .then(response => {
        setSingleProduct(response.data);
        setLoading(false);
      })
      .catch(err => {
        console.error('获取单个产品失败:', err);
        setError(err.message);
        setLoading(false);
      });
  }, []);

  return {
    products,
    getTopProducts,
    singleProduct,
    getSingleProduct,
    loading,
    error
  }
};

export default useGetProduct;

Product组件:Product.js

import React, { useEffect } from "react";
import { useParams } from "react-router-dom";
import useGetProduct from "../hooks/useGetProduct";

const Product = () => {
  const { id } = useParams();
  const { singleProduct, getSingleProduct, loading, error } = useGetProduct();
    
  useEffect(() => {
    // 确保id存在时再发起请求
    if (id) {
      getSingleProduct(id);
    }
  }, [id, getSingleProduct]); // 添加依赖,确保id变化时重新请求
   
  // 处理不同状态的UI展示
  if (loading) return <div>加载中...</div>;
  if (error) return <div>加载失败: {error}</div>;
  if (!singleProduct) return <div>未找到对应产品</div>;

  return ( 
    <div>
      <p>Product: {singleProduct.name}</p>
      {/* 可扩展展示更多产品信息 */}
      <p>品牌: {singleProduct.brand}</p>
      <p>价格: ${singleProduct.price}</p>
    </div>
  );
};
 
export default Product;

关键修改说明

  • 修正了API请求后缀的拼写错误,保证请求能正常响应。
  • 让getSingleProduct接收外部传入的productId参数,实现根据路由动态获取产品详情。
  • 使用useCallback包裹请求函数,避免组件重复渲染时创建新函数,同时让useEffect的依赖更稳定。
  • 添加loading和error状态,优化用户体验,明确展示请求的不同阶段状态。
  • 完善useEffect的依赖数组,确保路由参数id变化时自动重新发起请求。

内容的提问来源于stack exchange,提问作者Zohre Omidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:01:01