MUI Autocomplete组件显示undefined的问题排查与解决
解决MUI Autocomplete输入框显示undefined的问题
问题核心原因
你的代码关键问题是状态类型不匹配:selectedMetro初始为字符串,但Autocomplete的选项是对象数组,组件无法将字符串状态正确映射到选项的显示标签,再加上isOptionEqualToValue的匹配逻辑混乱,最终导致输入框显示undefined。
具体修复步骤
- 统一状态类型:将
selectedMetro改为存储对象类型(对应metros数组中的项),而非字符串。 - 修正初始值逻辑:在获取
metros数据后,匹配初始的"Richmond, VA"对应的对象,设置为初始状态。 - 简化
isOptionEqualToValue匹配逻辑:只对比选项和选中值的唯一标识(比如metro字段)。 - 简化
handleSelectedMetro处理函数:直接处理选中的对象或清空操作。 - 修正请求逻辑:确保请求时使用选中对象的
metro字段。
修改后的关键代码片段
const Homepage = () => { const classes = useStyles(); // 初始状态改为null,后续设置为匹配的对象 const [selectedMetro, setSelectedMetro] = useState(null); const [top5ZipCodes, setTop5ZipCodes] = useState([]); const [switchStates, setSwitchStates] = useState({}); const mapRef = useRef(null); const [metros, setMetros] = useState([]); useEffect(() => { const url = `http://${config.server_host}:${config.server_port}/all_metros`; fetch(url) .then(res => res.json()) .then(resData => { setMetros(resData); // 初始化时找到对应初始值的对象 const initialMetro = resData.find(m => m.metro === "Richmond, VA"); setSelectedMetro(initialMetro); }) .catch(error => console.error('Error fetching metros:', error)); }, []); useEffect(() => { if (selectedMetro?.metro) { // 使用选中对象的metro字段发起请求 fetch(`http://${config.server_host}:${config.server_port}/top_zip_codes_by_metro/?metro=${selectedMetro.metro}`) .then(res => res.json()) .then(data => { if (data?.length > 0) { setTop5ZipCodes(data); const initialSwitchStates = data.reduce((acc, zipCode) => { acc[zipCode.zipcode] = false; return acc; }, {}); setSwitchStates(initialSwitchStates); } if (mapRef.current && data?.length > 0) { const bounds = L.latLngBounds( data.map(zipCode => [zipCode.lat, zipCode.lng]) ); mapRef.current.fitBounds(bounds, { padding: [50, 50] }); } }) .catch(error => { console.error('Error fetching top zip codes:', error); }); } }, [selectedMetro]); // 简化选中处理函数 const handleSelectedMetro = (event, data) => { setSelectedMetro(data || null); }; const handleSwitchToggle = (zipcode) => { setSwitchStates((prevSwitchStates) => ({ ...prevSwitchStates, [zipcode]: !prevSwitchStates[zipcode], })); }; return ( <div className={classes.root}> {/* 其他代码保持不变 */} <Autocomplete id="metro" options={metros} // 确保option是对象,直接返回metro字段 getOptionLabel={(option) => option.metro || ''} value={selectedMetro} onChange={handleSelectedMetro} renderInput={(params) => ( <TextField {...params} label="Type the desired metro" variant="outlined" sx={{ width: 360 }} /> )} // 简化匹配逻辑,只对比metro字段 isOptionEqualToValue={(option, value) => value === null || option.metro === value.metro } /> {/* 其他代码保持不变 */} </div> ); }
额外注意事项
- 确保
metros数组中的每一项都包含metro字段,否则getOptionLabel仍会出现undefined。 - 初始状态设为
null而非字符串,避免组件初始化时找不到匹配的选项。
内容的提问来源于stack exchange,提问作者C Spaniel
相关产品推荐
相关产品推荐

