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

React调用TheDogAPI读取'metric'属性报undefined错误求助

你遇到的TypeError: Cannot read properties of undefined (reading 'metric')报错,是因为页面首次渲染时,犬种数据的异步请求还未完成,此时items是你初始化的空数组,不存在height、weight属性,读取undefined的metric子属性就触发了错误。

解决步骤

1. 修正状态初始化,增加属性安全访问

你接口返回的是单条犬种对象,而非数组,所以初始值不要设为空数组,建议设为null,同时使用可选链运算符?.避免访问不存在的属性时报错。

2. 补全useEffect依赖项

你的请求依赖URL参数id,需要把id加入useEffect的依赖数组,否则后续id变化时不会重新请求对应数据。

3. 优化图片请求逻辑

原代码直接在img的src属性中调用getImage,且用原生DOM操作修改图片地址,不符合React设计规范,建议把图片地址存入state,在犬种数据请求成功后再触发图片请求。

修改后完整代码

import React from 'react'
import {useEffect, useState} from 'react';
import {Link} from 'react-router-dom'

const Page = () =>{
    // 从URL中获取ID参数
    const urlParams = new URLSearchParams(window.location.search);
    const id = urlParams.get('id');

    // 初始值改为null,适配接口返回的对象结构
    const [items, setItems] = useState(null)
    const [imageUrl, setImageUrl] = useState('')
    const [loading, setLoading] = useState(true)

    // 把id加入依赖数组
    useEffect(() => {
      if (!id) return
      const getBreeds = async () =>{
        setLoading(true)
        const res = await fetch(
         `https://api.thedogapi.com/v1/breeds/${id}`
        );
        const data = await res.json();
        setItems(data)
        setLoading(false)
      }
      getBreeds()
    }, [id])

    // 犬种数据加载完成后请求图片
    useEffect(() => {
      if (!items?.reference_image_id) return
      const getImage = async (imageId) => {
        const res = await fetch(`https://api.thedogapi.com/v1/images/${imageId}`)
        const data = await res.json()
        setImageUrl(data.url)
      }
      getImage(items.reference_image_id)
    }, [items])

    // 加载中状态展示
    if (loading) return <div>加载中...</div>

    return(
        <div className="" 
             style={{
               "display": "flex",
               "position":"relative",
               "justify-content": "center",
               "align-items": "center",
               'flex-direction': "column",
               "maxWidth":"100%",
               "maxHeight":"100%"
             }}>

            <h6 className="card-subtitle mb-2 text-muted text-center"  style={{"marginTop":"5px"}}>犬种名称</h6>
            <h5 className="card-title text-center">{items.name}</h5>
            
            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>培育用途</h6>
            <h5 className="card-title text-center">{items.bred_for}</h5>
            
            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>所属组别</h6>
            <h5 className="card-title text-center">{items.breed_group}</h5>
            
            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>性格特点</h6>
            <h5 className="card-title text-center">{items.temperament}</h5>
            
            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>寿命</h6>
            <h5 className="card-title text-center">{items.life_span}</h5>
            
            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>身高</h6>
            <h5 className="card-title text-center">{items.height?.metric || '暂无数据'}</h5>

            <h6 className="card-subtitle mb-2 text-muted text-center" style={{"marginTop":"5px"}}>体重</h6>
            <h5 className="card-title text-center">{items.weight?.metric || '暂无数据'}</h5>


            <img className ="image" 
            src={imageUrl}
            style={{ "maxHeight": "300px", "maxWidth": "300px", "marginBottom":"15px" }}
            alt={items.name}/>

            <Link to="/" className="btn btn-primary">返回首页</Link>
        </div>
        
    );
}

export default Page;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:45:05