You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI Autocomplete组件显示undefined的问题排查与解决

解决MUI Autocomplete输入框显示undefined的问题

问题核心原因

你的代码关键问题是状态类型不匹配:selectedMetro初始为字符串,但Autocomplete的选项是对象数组,组件无法将字符串状态正确映射到选项的显示标签,再加上isOptionEqualToValue的匹配逻辑混乱,最终导致输入框显示undefined。

具体修复步骤

  1. 统一状态类型:将selectedMetro改为存储对象类型(对应metros数组中的项),而非字符串。
  2. 修正初始值逻辑:在获取metros数据后,匹配初始的"Richmond, VA"对应的对象,设置为初始状态。
  3. 简化isOptionEqualToValue匹配逻辑:只对比选项和选中值的唯一标识(比如metro字段)。
  4. 简化handleSelectedMetro处理函数:直接处理选中的对象或清空操作。
  5. 修正请求逻辑:确保请求时使用选中对象的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:54:57