Strapi结合React按ID查询元素详情仅首次生效问题
问题根因
你遇到的报错核心是两个逻辑漏洞:
- 没有做加载状态兜底:
Animaux初始值是空数组,不管是首次进入页面,还是点击其他条目切换路由触发新请求的等待阶段,组件都会优先执行渲染逻辑,这时候直接访问Animaux.data.id这类深层属性,相当于在空数组上读取不存在的data字段,拿到undefined后再往下读属性就会直接抛出类型错误。第一次点击能正常显示,只是因为首次请求响应速度足够快,在组件首次渲染报错前就完成了状态更新,属于偶现的正常,不是逻辑没问题。 - 路由参数变化时没有重置状态:id更新触发新请求的过程中,页面没有阻断渲染逻辑,旧状态、错误状态残留会直接导致渲染逻辑读取到不符合预期的值,触发报错。另外你贴的代码里JSX部分有错位的括号、多余的注释闭合符,属于语法问题,也会干扰渲染。
修复步骤
- 新增loading状态,请求完成前不渲染详情内容,从根源避免读取未赋值的状态
- 每次id变化发起新请求前,清空旧的详情数据、重置错误状态,避免旧数据干扰
- 修正JSX语法错误,对传入的
animal属性加可选链兜底,避免props为空时触发额外报错 - 统一接口地址的模板字符串写法,减少拼接错误
修复后的完整代码如下:
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import axios from 'axios'; const Articles = ({ animal }) => { const [error, setError] = useState(null); // 初始值改为null,方便判断是否已拿到接口数据 const [Animaux, setAnimaux] = useState(null); const [loading, setLoading] = useState(false); const { id } = useParams(); useEffect(() => { // 新请求发起前重置所有状态 setLoading(true); setError(null); setAnimaux(null); axios .get(`http://localhost:1337/api/animaux/${id}`) .then(({ data }) => setAnimaux(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)); }, [id]); // 加载中优先显示加载提示 if (loading) return <div>内容加载中...</div>; // 有错误优先显示错误提示 if (error) return <div>请求出错:{error.message}</div>; // 数据未就绪时阻断后续渲染 if (!Animaux?.data) return null; return ( <div> <p>Id : {Animaux.data.id}</p> <p>Nom : {Animaux.data.attributes.nom}</p> <p>Description : {Animaux.data.attributes.Description}</p> <div key={animal?.id} className="card"> <span className="btn btn-primary">Voir {animal?.attributes?.nom}</span> </div> </div> ); }; export default Articles;
替换原有代码后,不管是首次加载还是反复切换不同条目,都不会再出现单次生效后报错的问题。
内容的提问来源于stack exchange,提问作者Megane Lemaitre
相关产品推荐
相关产品推荐

