React报错Objects are not valid as react child 动态访问对象属性渲染失败
问题场景
变量clickedCountry存储了国家信息对象,结构为{name: x, population: x, region: x, capital: x...},使用clickedCountry.population这类点语法固定访问属性时可以正常渲染,改为动态拼接属性名访问时,抛出如下报错:
Objects are not valid as React children(对象不能作为React的合法子元素渲染)
复现代码如下:
{ ['Name', 'Population', 'Region','Capital', 'Currencies', 'Languages'].map(el => { let name = el.toLowerCase() console.log(typeof(name)) // 打印结果为string console.log(name) // 打印结果为population、region等预期属性名 return ( <Typography gutterBottom component="div"> <span className='font-600'>{el}:</span> {clickedCountry.name} // 正常渲染 {clickedCountry[name]} // 触发报错 {clickedCountry[`${name}`]} // 触发报错 {clickedCountry[`${el.toLowerCase()}`]} // 触发报错 </Typography> ) }); }
经控制台校验,动态生成的属性名是字符串类型、值也和预期一致,无法定位报错原因。
根本原因
报错和动态属性访问的写法完全无关,核心是字段值类型不匹配:
你遍历的6个字段中,currencies(货币)、languages(语言)两个字段的返回值不是字符串、数字这类可直接渲染的基础类型,而是嵌套对象/数组结构。
- 写死
clickedCountry.name时,始终访问字符串类型的name字段,符合React渲染要求,所以正常 - 动态遍历到
currencies、languages字段时,取到的值是对象/数组,React不支持直接将对象作为子元素渲染,就会抛出该错误。
你可以在取值后加一行console.log(clickedCountry[name])验证,遍历到这两个字段时,控制台输出的一定是结构化的对象/数组,而非基础类型值。
修复方案
对非基础类型的字段单独做格式化处理,转成字符串或合法JSX结构后再渲染,同时给遍历的根节点加上唯一key属性避免渲染警告:
{ ['Name', 'Population', 'Region','Capital', 'Currencies', 'Languages'].map(el => { const fieldKey = el.toLowerCase() let fieldValue = clickedCountry[fieldKey] // 单独格式化对象/数组类型字段,可按接口实际返回结构调整取值逻辑 if (fieldKey === 'currencies') { fieldValue = Object.values(clickedCountry.currencies).map(curr => curr.name).join('、') } if (fieldKey === 'languages') { fieldValue = Object.values(clickedCountry.languages).join('、') } return ( <Typography gutterBottom component="div" key={el}> <span className='font-600'>{el}:</span> {fieldValue} </Typography> ) }); }
内容的提问来源于stack exchange,提问作者Jenny
相关产品推荐
相关产品推荐

