React报错Uncaught TypeError:无法读取undefined的toString属性解决
问题根因
你遇到的Uncaught TypeError: Cannot read properties of undefined (reading 'toString') 是React组件异步渲染场景下的典型边界错误,和你贴的代码里三个未做兜底的逻辑直接相关:
- 组件初始渲染时,父组件传递的
dataprop 大概率是异步接口返回值,首屏阶段data为undefined,直接解构id会触发底层转义逻辑的toString调用报错 - 模板字符串拼接请求路径时,会对插入的
id值隐式调用toString(),如果id为无原型对象(通过Object.create(null)创建)、未定义的特殊值,就会直接抛错 - axios请求未加错误捕获、未做请求竞态处理,接口返回异常时也可能触发同类报错
排查步骤
按优先级逐点验证即可快速定位:
- 在
let { id } = data;这行下加console.log('data值:', data, 'id值:', id),看首次渲染时data是否为undefined、id的类型是否为string/number等可转字符串的基本类型 - 打开浏览器网络面板,看报错时发送的请求路径是否为
http://localhost:3001/courses/undefined,如果是就说明首屏渲染时id还没赋值就触发了请求 - 检查接口返回值是否有异常,是否存在404/500等错误状态未被捕获
修复代码
直接替换核心组件代码即可覆盖所有边界场景:
const CourseTypeFour = ({ data = {}, classes, bgWhite }) => { // 给data加空对象默认值,避免首屏解构报错 const { id } = data; const [courseObject, setCourseObject] = useState({}); useEffect(() => { // id为无效值时直接终止逻辑,不发请求 if (id == null) { return; } // 增加请求取消逻辑,处理id快速变化的竞态问题 const controller = new AbortController(); axios.get(`http://localhost:3001/courses/${id}`, { signal: controller.signal }).then((response) => { if (response.data) { setCourseObject(response.data); } }).catch((err) => { // 忽略主动取消请求的报错,其他错误打印日志 if (err.name !== 'CanceledError') { console.error('课程数据请求失败:', err); } }); // 组件卸载或id变化时,取消上一次未完成的请求 return () => controller.abort(); }, [id]); return ( // 原有JSX逻辑 ) } export default CourseTypeFour;
补充说明
如果改完后仍有报错,检查return的JSX逻辑里是否有对courseObject下未定义属性直接调用toString()的场景——因为接口请求是异步的,首次渲染时courseObject是空对象,直接读取深层属性做toString调用也会触发完全一样的报错,这种情况给渲染字段加可选链即可,比如courseObject?.name?.toString()。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

