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

React中fetch捕获ERR_CONNECTION_REFUSED时无法setState的问题

问题分析与解决方案

核心问题排查

你提到catch块里的console.log能正常输出,但setError无法更新状态,可能的原因及对应解决方法如下:

1. fetch请求参数格式错误(隐性问题)

你的fetch请求中body直接传入了对象,而fetch要求body必须是序列化后的JSON字符串,否则会导致请求格式错误(虽然当前是故意断网测试,但修复后才能保证正常请求的正确性):

body: JSON.stringify({
  email: email,
  password: password,
}),

2. await与then/catch混用导致异步流程混乱

在async函数中混用await和then/catch会让异步逻辑的作用域变得模糊,可能导致状态更新失效。建议统一用try/catch处理await的异步错误:

async function login(email, password) {
  try {
    const response = await fetch("http://localhost:8080/auth/login", {
      method: "POST",
      body: JSON.stringify({ email, password }),
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
    });
    // 注意:fetch仅在网络错误时抛错,HTTP状态码错误(如400/500)不会进入catch,需手动判断
    if (!response.ok) {
      throw new Error("请求失败");
    }
    const data = await response.json();
    // 处理登录成功逻辑
  } catch (error) {
    console.log("Error from server", error);
    setError("Error from server");
  }
}

3. 组件在异步操作完成前已卸载

如果触发login后组件被卸载(比如用户跳转页面),此时调用setError会被React忽略,无法触发重新渲染。可以通过挂载状态判断避免:

const [error, setError] = React.useState("");
const isMounted = React.useRef(true);

React.useEffect(() => {
  return () => {
    isMounted.current = false;
  };
}, []);

async function login(email, password) {
  try {
    // ... 省略fetch逻辑
  } catch (error) {
    if (isMounted.current) {
      setError("Error from server");
    }
  }
}

4. 状态未正确绑定到Typography组件

检查你的Typography组件是否正确使用了error状态,比如:

<Typography color="error">{error}</Typography>

确保没有拼写错误,或状态被其他逻辑意外覆盖。

额外提示

  • fetch的错误处理有特殊性:只有网络层面的错误(如连接拒绝、断网)才会进入catch,HTTP状态码错误(如401、500)不会触发catch,需要手动通过response.ok判断并抛出错误。
  • 不要在useEffect中依赖error来触发setError,这会导致无限循环(setError更新error后会再次触发useEffect)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:14