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

使用useEffect调用API后切换路由报错:TypeError: func.apply is not a function

问题分析与解决方案

这个问题我之前也碰到过,根源其实很简单——你把async直接传给了useEffect的回调函数!

为什么会报错?

React的useEffect钩子对回调函数的返回值有严格要求:它要么返回一个用于清理操作的函数,要么返回undefined。但async函数的返回值是一个Promise对象,当你点击Link跳转路由导致当前组件卸载时,React会尝试把这个Promise当作清理函数来调用,自然就会抛出TypeError: func.apply is not a function——毕竟Promise不是函数,没法执行apply方法。

你用dummy数据时没问题,大概率是因为你当时没给useEffect加async回调,或者同步操作下Promise立即resolved,但本质上这个写法的隐患一直存在。

修复方案

把useEffect的外层async去掉,保持内部的fetchData为async函数即可,同时建议加上错误处理和请求取消逻辑(避免组件卸载后请求完成触发状态更新警告):

useEffect(() => {
  // 创建AbortController用于取消请求
  const abortController = new AbortController();
  
  const fetchData = async () => {
    try {
      const result = await axios('http://192.168.1.17:8000/stacks', {
        signal: abortController.signal // 绑定取消信号
      });
      setDisplayPosts(result.data);
      setIsLoading(false);
    } catch (error) {
      // 忽略主动取消的错误
      if (error.name !== 'AbortError') {
        console.error('加载Stack数据失败:', error);
        setIsLoading(false);
      }
    }
  };

  fetchData();

  // 组件卸载时取消请求
  return () => abortController.abort();
}, []);

额外说明

这样修改后,useEffect的回调返回的是一个清理函数(取消请求的逻辑),完全符合React的要求,跳转路由时就不会再触发那个错误了。同时,添加错误处理也能让你在API请求失败时更优雅地处理状态,避免页面一直处于加载状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 07:44:09