React组件间动物数据传递及详情页undefined错误求助
解决React详情页数据传递与错误处理问题
一、先修复当前基于ID的方案(稳定且符合URL规范)
你的现有方案是React路由的标准实现方式,问题出在两个细节上:
filter返回的是数组,应该用find直接获取匹配的单个对象- 未处理
id不存在或找不到对应数据的边界情况
修改后的代码:
export const AnimalsDetails = () => { const [mammal, setMammal] = useState(null); const { id } = useParams(); useEffect(() => { // 用find替代filter,直接返回匹配的单个动物对象 const foundMammal = mammalsData.find(thisMammal => thisMammal.id === id); setMammal(foundMammal); }, [id]); // 处理数据未加载或未找到的情况 if (!mammal) { return <AnimalsDetailsContainer>未找到该动物信息</AnimalsDetailsContainer>; } return ( <AnimalsDetailsContainer> <div>{mammal.id}</div> <div>{mammal.animal}</div> {/* 按需渲染其他属性 */} </AnimalsDetailsContainer> ) };
二、直接传递动物对象的方案(适合新手快速实现)
如果想跳过ID匹配步骤,直接把动物对象传到详情页,可以利用React Router的state属性:
1. 修改卡片组件的跳转逻辑
在AnimalsCard中,使用useNavigate跳转时携带完整的动物对象:
import { useNavigate } from 'react-router-dom'; const AnimalsCard = (animalData) => { const navigate = useNavigate(); const handleClick = () => { // 跳转时将整个动物对象存入state navigate(`/${animalData.id}`, { state: { animalData } }); }; return ( <div onClick={handleClick}> <img src={animalData.img} alt={animalData.animal} /> <h3>{animalData.animal}</h3> </div> ); };
2. 在详情页接收state数据
用useLocation获取跳转时携带的state数据:
import { useLocation } from 'react-router-dom'; export const AnimalsDetails = () => { const location = useLocation(); // 从state中取数据,同时做兜底处理 const mammal = location.state?.animalData || null; if (!mammal) { return <AnimalsDetailsContainer>未找到该动物信息</AnimalsDetailsContainer>; } return ( <AnimalsDetailsContainer> <div>{mammal.animal}</div> <img src={mammal.img} alt={mammal.animal} /> <div>栖息地:{mammal.habitat}</div> {/* 按需渲染其他属性 */} </AnimalsDetailsContainer> ) };
关键注意点
直接传对象的方式有个局限:如果用户刷新详情页或直接输入URL进入,state会丢失,仍会出现数据为空的情况。建议结合两种方案做兜底:
import { useLocation, useParams } from 'react-router-dom'; export const AnimalsDetails = () => { const location = useLocation(); const { id } = useParams(); const [mammal, setMammal] = useState(null); useEffect(() => { // 优先使用state中的数据 let animalData = location.state?.animalData; // 如果state无数据,再通过ID从数组查找 if (!animalData && id) { animalData = mammalsData.find(item => item.id === id); } setMammal(animalData); }, [location.state, id]); if (!mammal) { return <AnimalsDetailsContainer>未找到该动物信息</AnimalsDetailsContainer>; } return ( <AnimalsDetailsContainer> {/* 渲染内容 */} </AnimalsDetailsContainer> ) };
内容的提问来源于stack exchange,提问作者kwi
相关产品推荐
相关产品推荐

