React递归提取嵌套对象报can't convert undefined to object如何解决?
问题修复方案
你遇到的问题由三个核心原因导致:
- React 状态更新为异步行为,执行
setBakery后立刻打印bakery获取的是更新前的旧值,并非状态未成功写入 - 页面首次渲染时
bakery初始值为空数组,监听bakery的useEffect会先触发一次执行,此时extractNestedData取objects[0]得到undefined,传入Object.values就会触发类型报错 - 原有递归逻辑存在两个错误:用
const声明的data变量被二次赋值,以及递归调用返回的结果没有被收集到最终输出数组中,导致无法提取嵌套数据
以下是修复后的完整可运行代码:
import { useState, useEffect } from 'react'; import axios from 'axios'; // API Call const fetchData = async () => { try { const response = await axios.get( "https://60d007f67de0b200171079e8.mockapi.io/bakery" ); console.log('fetched data', response.data) return response.data; } catch (err) { console.error(err); return []; } }; const extractData = (objects) => { const objectKeys = []; // 加非空判断,避免处理undefined if (!objects || typeof objects !== 'object') return objectKeys; const values = Object.values(objects) values.forEach(val => { if (val && typeof val === "object") { // 收集递归返回的嵌套值 objectKeys.push(...extractNestedData(val)) } else { objectKeys.push(val) } }) return objectKeys; } const extractNestedData = (objects) => { // 兼容空入参 if (!objects || !Array.isArray(objects) || objects.length === 0) return []; const object = objects[0]; // 把const改为let,允许重新赋值 let data = [] data = extractData(object) return data; } export default function App() { const [bakery, setBakery] = useState([]) const [flatBakery, setFlatBakery] = useState([]) useEffect(() => { let mount1 = true; if(mount1){ fetchData().then((randomData) => { setBakery(randomData) // 这里打印的是旧值,属于正常现象 console.log('set后立刻打印的bakery(旧值)', bakery) }) } return () => { mount1 = false;} }, []); useEffect(() => { let mount2 = true; if (mount2 && bakery.length > 0) { // 只有bakery有值时才执行提取逻辑 setFlatBakery(extractNestedData(bakery)); // 这里可以拿到更新后的bakery值 console.log('更新后的bakery', bakery) } return () => mount2 = false; }, [bakery]) // 可以在这里打印flatBakery验证提取结果 console.log('扁平化后的数据', flatBakery) return ( <div> Hello </div> ); }
内容的提问来源于stack exchange,提问作者Aman Rathod
相关产品推荐
相关产品推荐

