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

如何在模板字面量中使用Async Await?React组件场景问题

解决React组件中Autocomplete渲染异步数据的问题

你当前的写法存在两个核心问题:

  • 直接在模板字符串里执行异步函数,会返回Promise对象,模板字符串会把它转为[object Promise],所以显示的是字符串字面量而非实际邮编
  • 异步操作的结果无法直接同步渲染到UI中,需要结合React状态管理来处理

正确实现步骤:

  1. 用状态存储每个选项的邮编:通过useState创建一个对象,以place_id为键,存储对应的邮编或加载状态
  2. 封装异步请求函数:用useCallback包裹请求逻辑,避免重复创建函数,同时处理请求竞态问题
  3. 在渲染选项时触发请求并处理状态:渲染每个选项时,检查是否已有对应的邮编,没有则触发请求,根据状态显示加载提示或实际邮编

完整代码示例:

import { useState, useCallback } from "react";
import { Autocomplete, TextField } from "@mui/material";
import usePlacesAutocomplete, { getGeocode, getZipCode } from "use-places-autocomplete";

const Places = () => {
  // 存储每个place_id对应的邮编,格式:{ [placeId]: string | "loading" | null }
  const [zipCodes, setZipCodes] = useState({});

  // 封装获取邮编的异步函数,处理竞态问题
  const fetchZipCode = useCallback(async (placeId) => {
    // 标记为加载中
    setZipCodes(prev => ({ ...prev, [placeId]: "loading" }));
    try {
      const results = await getGeocode({ placeId });
      const zipCode = getZipCode(results[0], true);
      // 更新状态,仅当当前请求的placeId未被其他请求覆盖时才更新
      setZipCodes(prev => ({ ...prev, [placeId]: zipCode }));
    } catch (error) {
      console.error("获取邮编失败:", error);
      setZipCodes(prev => ({ ...prev, [placeId]: null }));
    }
  }, []);

  return (
    <Autocomplete
      options={[]} // 替换为你的地址数据源
      getOptionLabel={(option) => option.description}
      renderOption={(props, option) => {
        const placeId = option.place_id;
        // 若未加载过邮编,触发请求
        if (!zipCodes[placeId]) {
          fetchZipCode(placeId);
        }
        const zipCode = zipCodes[placeId];

        return (
          <li {...props}>
            {option.description}
            {/* 根据状态显示不同内容 */}
            {zipCode === "loading" && " (加载中...)"}
            {zipCode && zipCode !== "loading" && ` (邮编:${zipCode})`}
            {zipCode === null && " (获取邮编失败)"}
          </li>
        );
      }}
      renderInput={(params) => <TextField {...params} label="搜索地址" />}
    />
  );
};

export default Places;

关键说明:

  • 状态管理:用zipCodes对象存储每个地址的邮编,避免重复请求同一地址的邮编
  • 竞态处理:更新状态时先解构之前的状态,确保当前请求的结果不会被更早发起但延迟返回的请求覆盖
  • UI反馈:添加加载状态和错误状态的提示,提升用户体验

内容的提问来源于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 17:35:27