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

ItemDetailPage使用axios调用API时出现解构null的TypeError问题

解决React组件中解构null状态导致的TypeError错误

问题描述

实现ItemDetailPage组件时,调用http://localhost:5001/products/${id}接口获取数据,出现错误:TypeError: 无法解构product的'prodImageURL'属性,因为product为null。

错误代码如下:

import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

function ItemDetailPage() {
  const { id} = useParams();
  const [product, setProduct] = useState(null);
  const { prodImageURL, name, funding, personnel, price } = product;
  console.log("prodImageURL, name, funding, personnel, price",prodImageURL, name, funding, personnel, price);
  const imgURL_full = `http://localhost:5001/${prodImageURL}`;
  console.log("product", product);

  useEffect(() => {
    axios.get(`http://localhost:5001/products/${id}`)
      .then((response) => {
        setProduct(response.data);
      })
      .catch((error) => {
        console.error(error);
      });
  }, [id]);

  if (!product) {
    return <div>삼품이 없습니다</div>;
  }

  return (
    <div>
      <div className='detail-info'>
      <img src={imgURL_full} alt={name} />
      <div className='detail-text'>
          <p className='detail-title'>{name}</p>
          <p className='detail-funding'>펀딩 진행중:{funding}</p>
          <p className='detail-personnel'>펀딩 인원:{personnel}</p>
          <p>가격: {price}</p>
      </div>
      </div>
       </div>
  );
}

export default ItemDetailPage;

错误原因

组件初始化时product状态被设为null,但你在组件顶层直接对product进行属性解构。React组件的渲染流程是先执行顶层代码,再处理useEffect和条件判断。所以首次渲染时,解构null的属性会直接触发TypeError,后续的if (!product)判断根本来不及执行。

解决方案

核心是确保只在product不为null时才解构其属性,以下是两种常用修复方式:

方式一:将解构移到product存在的判断之后

把属性解构代码放到if (!product)的判断逻辑之后,确保只有当product有值时才执行解构操作:

import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

function ItemDetailPage() {
  const { id} = useParams();
  const [product, setProduct] = useState(null);

  useEffect(() => {
    axios.get(`http://localhost:5001/products/${id}`)
      .then((response) => {
        setProduct(response.data);
      })
      .catch((error) => {
        console.error(error);
      });
  }, [id]);

  if (!product) {
    return <div>상품이 없습니다</div>;
  }

  // 确认product存在后再解构属性
  const { prodImageURL, name, funding, personnel, price } = product;
  const imgURL_full = `http://localhost:5001/${prodImageURL}`;

  return (
    <div>
      <div className='detail-info'>
        <img src={imgURL_full} alt={name} />
        <div className='detail-text'>
          <p className='detail-title'>{name}</p>
          <p className='detail-funding'>펀딩 진행중:{funding}</p>
          <p className='detail-personnel'>펀딩 인원:{personnel}</p>
          <p>가격: {price}</p>
        </div>
      </div>
    </div>
  );
}

export default ItemDetailPage;

方式二:使用可选链和默认值进行安全解构

如果需要在顶层保留解构逻辑,可以使用可选链操作符(??)和默认值,避免null解构报错:

import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

function ItemDetailPage() {
  const { id} = useParams();
  const [product, setProduct] = useState(null);
  
  // 用?? {}将null转为空对象,再配合默认值避免undefined
  const { prodImageURL = "", name = "", funding = 0, personnel = 0, price = 0 } = product ?? {};
  // 只有product存在时才拼接完整图片地址
  const imgURL_full = product ? `http://localhost:5001/${prodImageURL}` : "";

  useEffect(() => {
    axios.get(`http://localhost:5001/products/${id}`)
      .then((response) => {
        setProduct(response.data);
      })
      .catch((error) => {
        console.error(error);
      });
  }, [id]);

  if (!product) {
    return <div>상품이 없습니다</div>;
  }

  return (
    <div>
      <div className='detail-info'>
        <img src={imgURL_full} alt={name} />
        <div className='detail-text'>
          <p className='detail-title'>{name}</p>
          <p className='detail-funding'>펀딩 진행중:{funding}</p>
          <p className='detail-personnel'>펀딩 인원:{personnel}</p>
          <p>가격: {price}</p>
        </div>
      </div>
    </div>
  );
}

export default ItemDetailPage;

两种方式中,方式一逻辑更清晰,严格控制了解构时机,避免多余的默认值设置,推荐使用。

内容的提问来源于stack exchange,提问作者조민성

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:54:51