使用react-responsive-combo-box实现语言选择返回[object Object]问题排查
核心异常根因
- 组件传参逻辑错位:
react-responsive-combo-box要求options属性传入原始数据数组(字符串、数字、普通对象均可),组件会内部遍历数组,把每一项传给自定义的renderOptions方法生成下拉选项DOM。 - 你当前代码提前把原始数据map成了带样式的React JSX元素,再把这些JSX塞到
options里传给组件,完全颠倒了数据和渲染的分层逻辑。组件触发选中回调时,回传的就是你塞进去的JSX对象,当这个对象被放到页面文本区渲染时,会被JS自动转为普通字符串,最终就出现了[object Object]的显示异常。 - 附带的逻辑缺陷:
- 给
defaultIndex设置的4已经超过实际选项总数(2个),会触发组件索引越界警告 - 原代码用
selectedOption.length > 0做选中态判断,这个逻辑只适配字符串类型的状态,拿到对象类型的状态时判断完全失效 - 占位符文案写的是选择国家,和实际选择语言的场景不匹配
- 给
修正方案
把提前生成JSX的渲染逻辑全部挪到renderOptions回调里,options直接传原始语言数据集:
- 不再提前map原始数据生成JSX,把
props.dataSet直接作为options传给组件 - 把原map里的多列宽度控制、字段渲染逻辑,全部移到
renderOptions的回调中,接收组件遍历传入的每一条原始语言数据 - 修正选中/高亮状态的判断逻辑,从判断字符串长度改成判断选中对象是否存在
- 移除越界的
defaultIndex参数,替换匹配场景的占位符文案
调整后的组件代码
import React, { useState } from "react"; import ComboBox from "react-responsive-combo-box"; export default function ComboBoxLang(props) { const [selectedOption, setSelectedOption] = useState(null); const [highlightedOption, setHighlightedOption] = useState(null); // 直接使用原始数据集,不提前生成JSX const options = props.dataSet; return ( <div> <h1>React Combo Box</h1> <p> 已选选项 -{" "} <span style={{ fontWeight: "bold" }}> {selectedOption ? selectedOption.language_name : "None"} </span> </p> <p> 高亮选项 -{" "} <span style={{ fontWeight: "bold" }}> {highlightedOption ? highlightedOption.language_name : "None"} </span> </p> <ComboBox options={options} placeholder="请选择语言" optionsListMaxHeight={300} style={{ width: "500px", margin: "0 auto", marginTop: "50px" }} focusColor="#20C374" // 接收组件传入的原始数据,自定义渲染下拉选项 renderOptions={(item) => { const columnWidth = props.columnsWidth; const keys = Object.keys(columnWidth); const renderedColumns = keys.map(columnName => ( <div key={columnName} style={{ display: "inline-block", width: columnWidth[columnName] }} > {item[columnName]} </div> )); return ( <div className="comboBoxOption" key={item.id}> {renderedColumns} </div> ) }} onSelect={(option) => setSelectedOption(option)} onChange={(event) => console.log(event.target.value)} enableAutocomplete onOptionsChange={(option) => setHighlightedOption(option)} /> </div> ); }
调整后效果说明
onSelect、onOptionsChange回调返回的就是完整的原始语言对象,你可以直接把整个对象存在状态里,后续需要取语言代码、翻译引擎信息做其他模块联动时,直接读对象对应的字段即可,不需要额外格式转换。- 自动补全功能不受影响,组件会自动匹配原始对象里的字符串字段做搜索过滤,和自定义的多列渲染逻辑互不干扰。
- 后续要扩展展示字段时,只需要在传入的
columnsWidth配置里新增对应字段的宽度,renderOptions里的渲染逻辑会自动适配生成新列。
内容的提问来源于stack exchange,提问作者Vlad SD
相关产品推荐
相关产品推荐

