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

React(TypeScript)函数式组件调用AWS API遇报错求助

React异步API对接与状态更新问题

问题背景

我是React新手,尤其不熟悉React与后端服务的对接。我有一个React函数式组件Game,用于维护当前局面的评估值,同时已创建AWS API返回(-10,10)范围内的随机评估数值。我在组件中编写了如下代码:

const [evaluation, setEvaluation] = React.useState<number>(0.0);

// ...

const getEvalAfterMove = async (board: string[], nextPlayer: string) => {
    async function fetchData() {
        const response = await fetch('my/api/link');
        const data = await response.json();
        setEvaluation(data);
    }
        
    fetchData();
};

Game组件内包含GameGrid组件,后者由Square组件构成,getEvalAfterMove会逐层传递给每个Square组件,绑定到其onClick事件。但点击Square时,浏览器报TypeError: Failed to Fetch,无法获取数值,不过直接访问API调用URL能正常返回随机值的JSON。

我想确认:

  • getEvalAfterMove因异步是否独立于React应用执行?
  • 如何通过API调用在每次点击Square后更新evaluation状态?
  • 是否需要添加加载状态等待响应?

解答

1. 异步函数与React应用的关系

getEvalAfterMove并非完全独立于React执行:

  • 函数本身在React组件上下文里定义,触发时机由React的事件系统(Square的onClick)控制。
  • 内部的fetch异步请求会进入浏览器事件队列执行,脱离React的同步渲染流程,但调用setEvaluation更新状态时,该操作会触发React的状态更新机制,触发组件重新渲染。

2. 解决请求失败并正确更新状态

你遇到的Failed to Fetch几乎可以确定是CORS跨域问题:浏览器地址栏直接访问API不受同源策略限制,但React应用通过fetch发起的请求属于跨域请求,需要在AWS API Gateway中配置CORS规则,允许你的React应用域名的跨域访问(配置允许的Origin、请求方法、响应头)。

修复跨域后,优化代码以确保状态正确更新:

const getEvalAfterMove = async (board: string[], nextPlayer: string) => {
  try {
    const response = await fetch('my/api/link');
    // 检查请求是否成功(处理4xx/5xx状态码)
    if (!response.ok) {
      throw new Error(`请求失败: ${response.status}`);
    }
    const data = await response.json();
    setEvaluation(data);
  } catch (error) {
    console.error('获取评估值失败:', error);
    // 可选:添加错误提示逻辑,比如设置错误状态告知用户
  }
};

优化点:

  • 去掉嵌套的fetchData函数,简化代码结构
  • 用try/catch捕获请求过程中的所有错误,便于排查
  • 校验response.ok避免解析错误的响应内容

跨域问题解决后,每次点击Square触发getEvalAfterMove,请求成功后setEvaluation会更新状态,React会自动重新渲染组件展示最新的评估值。

3. 是否需要添加加载状态

建议添加加载状态,提升用户体验:当API请求未完成时,用户能看到明确的加载提示,不会误以为点击无效。实现方式如下:

// 新增加载状态
const [isLoading, setIsLoading] = React.useState<boolean>(false);

const getEvalAfterMove = async (board: string[], nextPlayer: string) => {
  setIsLoading(true);
  try {
    const response = await fetch('my/api/link');
    if (!response.ok) {
      throw new Error(`请求失败: ${response.status}`);
    }
    const data = await response.json();
    setEvaluation(data);
  } catch (error) {
    console.error('获取评估值失败:', error);
  } finally {
    // 无论请求成功或失败,都结束加载状态
    setIsLoading(false);
  }
};

然后在组件中根据isLoading展示对应内容:

{isLoading ? (
  <div>正在计算评估值...</div>
) : (
  <div>当前局面评估值: {evaluation}</div>
)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:42:28