React渲染Select菜单对象报非法子节点错误如何解决
报错信息
运行代码时抛出如下错误:Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
报错触发点为JSX中直接渲染{menu.props.options[0]},该值为普通JavaScript对象,不符合React可渲染节点规则。
报错根因
React JSX仅支持渲染三类内容:
- 原始类型值:字符串、数字、布尔值、null、undefined
- 合法React元素:即通过JSX编写的标签、组件返回值等
- 由上述可渲染内容组成的数组
普通JavaScript对象不在可渲染范围内,直接写入JSX模板就会抛出该错误。menu.props.options是Select组件内部存储下拉选项配置的数组,每一项都是存储了值、展示文本等属性的配置对象,本身不是可渲染的React节点。
修复方案
以下三种方案可直接落地,根据业务需求选择即可:
方案1:直接提取对象的展示字段渲染
如果仅需要展示第一个选项的文本内容,直接读取配置对象中存储展示文案的字段渲染即可,注意提前做空值判断避免空指针报错:
dropdownRender={menu => ( <div> {/* 替换原{menu.props.options[0]} 以下为修改部分 */} {menu.props.options?.[0] ? ( <div style={{padding: "5px 12px", cursor: "pointer"}}> {menu.props.options[0].text} </div> ) : null} {/* 修改部分结束 */} <div style={{ padding: "0 12px", height: 30, lineHeight: "30px", color: "#46C4C1" }} > Sugerencias </div> <Divider style={{ margin: 5 }} /> {menu} </div> )}
注意:如果你的选项配置中展示文案的字段不是
text(部分场景下为label),替换为对应字段名即可。
方案2:复用Select.Option组件渲染(推荐)
如果需要第一个选项和其他下拉项保持统一样式、支持点击选中逻辑,直接复用Select内置的Option组件渲染,不需要手动写样式和选中交互:
dropdownRender={menu => ( <div> {/* 替换原{menu.props.options[0]} 以下为修改部分 */} {menu.props.options?.[0] ? ( <Select.Option value={menu.props.options[0].text}> <span>{menu.props.options[0].text}</span> </Select.Option> ) : null} {/* 修改部分结束 */} <div style={{ padding: "0 12px", height: 30, lineHeight: "30px", color: "#46C4C1" }} > Sugerencias </div> <Divider style={{ margin: 5 }} /> {menu} </div> )}
方案3:过滤重复项避免第一个选项渲染两次
如果用方案2后发现第一个选项在自定义区域和下方下拉列表里各出现一次,可通过React.cloneElement过滤原menu中的第一个选项,避免重复渲染:
dropdownRender={menu => { const firstOption = menu.props.options?.[0]; // 过滤原下拉列表的第一项,避免重复展示 const filteredMenu = React.cloneElement(menu, { options: menu.props.options.slice(1) }); return ( <div> {firstOption ? ( <Select.Option value={firstOption.text}> <span>{firstOption.text}</span> </Select.Option> ) : null} <div style={{ padding: "0 12px", height: 30, lineHeight: "30px", color: "#46C4C1" }} > Sugerencias </div> <Divider style={{ margin: 5 }} /> {filteredMenu} </div> ) }}
注意事项
- 读取数组第一项时统一用可选链
?.做判断,选项列表为空时不会触发二次报错 - 如果第一个选项需要置灰不可点击,给
Select.Option添加disabled属性即可 - 若需要给第一个选项加自定义样式、额外操作按钮,直接在Option组件内部嵌套对应JSX即可,和普通列表项写法完全一致
内容的提问来源于stack exchange,提问作者Tomas Valentin
相关产品推荐
相关产品推荐

