React如何将API返回的JSON的symbol字段用作Autocomplete下拉选项并解决报错
报错原因定位
两个代码逻辑错误直接触发了这个length读取报错,和JSON解析没关系:
- 第一处是Autocomplete组件的options传值路径错误:代码里写的是
options={data.companies.symbol},但实际data.companies本身就是接口返回的、由公司对象组成的数组,这个数组根本没有顶层的symbol属性,最终传进组件的options值是undefined。而Autocomplete内部必须读取options的长度渲染选项,自然就抛出了Cannot read property 'length' of undefined的错误。 - 第二处是状态逻辑的冗余设计:把状态设计成
{ companies: [] }的嵌套结构,但实际接口返回的res.data本身就是完整的公司数组,嵌套存储本身不影响功能,但很容易在取数的时候多打一层路径出问题。
补充说明:axios默认会自动把接口返回的JSON格式字符串解析成JS对象,从贴的console输出能看到数据结构完全正确,不存在JSON解析失败的问题。
修复方案
两个方向选一个就行,核心是保证传入Autocomplete的options始终是合法的数组:
方案1:保留原状态结构做最小改动
只需要把options的取值路径改对,其他代码不动:
// 原错误代码 options={data.companies.symbol} // 修改为 options={data.companies}
改完之后因为初始状态data.companies就是空数组,异步请求回来之后会自动替换成接口返回的完整数组,组件就能正常拿到所有带symbol字段的选项对象。
方案2:优化状态结构更简洁
去掉没必要的对象嵌套,直接用数组存公司列表,代码更不容易写错:
export default function SymbolInput() { // 直接用数组存状态,不用嵌套对象 const [companies, setCompanies] = useState([]); const classes = useStyles(); useEffect(() => { Axios.get("<URL HERE>").then((res) => { setCompanies(res.data); // 依赖数组留空即可,setCompanies是React保证引用稳定的函数,不需要加入依赖 }, []); return ( <div className={classes.root}> <Autocomplete multiple // 直接把数组传给options options={companies} // 选项显示值取每个对象的symbol字段,逻辑和原需求一致 getOptionLabel={(option) => option.symbol} filterSelectedOptions renderInput={(params) => ( <TextField {...params} variant="outlined" label="股票代码筛选" placeholder="选择收藏标的" /> )} /> </div> ); }
额外容错优化
可以在传options的时候加个空值兜底,就算后续接口请求失败、返回结构异常,也不会触发同类报错:
options={companies || []}
内容的提问来源于stack exchange,提问作者yung peso
相关产品推荐
相关产品推荐

