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

Material UI Autocomplete无法获取异步函数返回的邮政编码问题

问题原因分析

你这段代码的核心问题出在异步操作的执行时机和React渲染机制不匹配:

  1. getPostCode是异步函数,当renderOption返回<li>时,异步请求还没完成,zipCode还是初始的空字符串,所以页面上看不到结果。
  2. 直接给局部变量zipCode赋值不会触发组件重新渲染,就算后续异步请求拿到了邮政编码,页面也不会自动更新显示。
解决方案

方案一:提前预加载所有选项的邮政编码(推荐)

在组件拿到data后,批量获取每个地点的邮政编码并存在选项对象里,避免渲染时频繁发起异步请求:

const Places = () => {
  const [optionsWithZip, setOptionsWithZip] = useState([]);

  useEffect(() => {
    const fetchZipCodes = async () => {
      const updatedOptions = await Promise.all(
        data.map(async (option) => {
          try {
            const results = await getGeocode({ placeId: option.place_id });
            const zipCode = getZipCode(results[0], true);
            return { ...option, zipCode };
          } catch (error) {
            console.log(error);
            return { ...option, zipCode: '' };
          }
        })
      );
      setOptionsWithZip(updatedOptions);
    };

    if (data.length > 0) {
      fetchZipCodes();
    }
  }, [data]);

  return (
    <Autocomplete       
      options={optionsWithZip}                    
      getOptionLabel={(option) => typeof option === 'string' ? option : option.description}
      filterOptions={(x) => x}
      renderInput={(params) => <TextField {...params} label='Location' />}
      onInputChange={(event, newValue) => setValue(newValue)}
      renderOption={(props, option) => (
        <li {...props} >              
          {`${option.terms[0].value}, ${option.terms[1]?.value}, ${option.zipCode}`}
        </li>
      )}
    />
  );
}

方案二:为单个选项单独处理异步请求

如果不想批量预加载,可以把每个选项的渲染拆成独立组件,用状态管理单个选项的邮政编码:

const Places = () => {
  const [zipCodesCache, setZipCodesCache] = useState({});

  const OptionItem = ({ props, option }) => {
    const [zipCode, setZipCode] = useState(zipCodesCache[option.place_id] || '');

    useEffect(() => {
      if (!zipCode) {
        const fetchZip = async () => {
          try {
            const results = await getGeocode({ placeId: option.place_id });
            const code = getZipCode(results[0], true);
            setZipCode(code);
            setZipCodesCache(prev => ({ ...prev, [option.place_id]: code }));
          } catch (error) {
            console.log(error);
          }
        };
        fetchZip();
      }
    }, [option.place_id, zipCode]);

    return (
      <li {...props} >              
        {`${option.terms[0].value}, ${option.terms[1]?.value}, ${zipCode}`}
      </li>
    );
  };

  return (
    <Autocomplete       
      options={data}                    
      getOptionLabel={(option) => typeof option === 'string' ? option : option.description}
      filterOptions={(x) => x}
      renderInput={(params) => <TextField {...params} label='Location' />}
      onInputChange={(event, newValue) => setValue(newValue)}
      renderOption={(props, option) => (
        <OptionItem props={props} option={option} />
      )}
    />
  );
}

内容的提问来源于stack exchange,提问作者Clippit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:46:20