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
相关产品推荐
相关产品推荐

