React Router刷新食谱详情页报Cannot read properties of undefined错误
问题成因
- 从列表页跳转到详情页时,Context 中的
recipes已经完成接口请求拿到了完整数据,find方法可以匹配到对应的食谱对象,所以访问.recipe属性正常 - 刷新详情页时,应用重新初始化,
recipes的初始值为空数组,find方法执行后返回undefined,直接访问undefined.recipe就会抛出对应错误 - 额外风险:如果用户是搜索其他关键词后进入的详情页,刷新后接口默认返回的是关键词为
pasta的食谱列表,大概率匹配不到之前的食谱,就算加了加载判断也会显示未找到
解决方案
1. 临时修复(适配当前逻辑,避免报错)
给 RecipeDetail 组件加空值判断,不要直接访问可能不存在的属性,修改后的代码如下:
import React,{useContext} from 'react'; import {useParams} from "react-router-dom" import {Context} from "../Context" function RecipeDetail(){ const {recipes} = useContext(Context) const {recipeId} = useParams() // 先对路由参数做解码,避免空格等编码字符匹配失败 const currentRecipe = recipes.find(recipe => recipe.recipe.label === decodeURIComponent(recipeId)) // 匹配不到时显示加载/未找到提示 if (!currentRecipe) { return <div>食谱加载中,请稍后重试</div> } return( <div> <h1>{currentRecipe.recipe.label}</h1> </div> ) } export default RecipeDetail
也可以用可选链语法简化,不需要提前判断:
<h1>{currentRecipe?.recipe?.label || '加载中'}</h1>
2. 优化路由参数(降低匹配失败概率)
当前用食谱名称当路由参数容易因为特殊字符、编码问题匹配失败,建议改用 Edamam 接口返回的食谱唯一 ID 当参数,跳转时取 recipe.recipe.uri 中提取的唯一标识,匹配准确率更高。
3. 彻底适配刷新场景
如果需要保证刷新详情页一定能加载到对应数据,不要只依赖全局的食谱列表,在详情页单独加单食谱查询逻辑:当全局列表匹配不到对应食谱时,用路由参数调用 Edamam 的单食谱查询接口拉取数据,不依赖全局列表的状态。
内容的提问来源于stack exchange,提问作者program
相关产品推荐
相关产品推荐

