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

React+TypeScript调用serviceCall报not a function错误如何解决

问题原因定位

1. 首要原因:Context 未正确包裹组件

你创建 ApiContext 时设置的默认值是空对象{},如果使用useUsers钩子的组件没有被<APIProvider>嵌套在内部,那么useApi()拿到的就是默认空对象,不存在serviceCall方法,就会抛出你遇到的serviceCall is not a function类型错误。
排查验证:检查调用useUsers的组件所在的父组件/路由结构,必须满足如下嵌套规则:

// 根组件示例结构
import { APIProvider } from "./providers/API";
import { GoogleAuthProvider } from "./providers/authentication";

function App() {
  return (
    <GoogleAuthProvider>
      <APIProvider>
        {/* 所有用到useApi、useGoogleAuth、useUsers的组件/路由都要放在这个层级内 */}
        <AppRoutes />
      </APIProvider>
    </GoogleAuthProvider>
  )
}

2. 次要问题:serviceCall 调用方式和定义不匹配

就算Context包裹正确,当前的调用写法也会报错:你定义的serviceCall要求传入一个包含endpoint、method、tokenId属性的对象(符合IServiceCallProps接口),但你现在调用时传的是三个分散的参数,参数格式不匹配。


修复方案

  1. 先按照上面的嵌套规则确认所有用到对应钩子的组件都在APIProvider的包裹范围内。
  2. 修改useUsers里的serviceCall调用方式,改为传入对象参数:
const signInUser = (tokenId: string) => {
  serviceCall({
    endpoint: "/users/signin",
    method: "GET",
    tokenId: tokenId
  })
    .then(() => console.log("User signed in"))
    .catch(() => {
      signOut();
      setTokenId();
    });
};
  1. (可选TS优化)给Context加上明确类型定义,避免后续出现同类隐式问题,还能在开发阶段快速定位未被Provider包裹的错误:
// 在APIProvider文件内提前定义Context类型
interface IApiContext {
  serviceCall: (props: IServiceCallProps) => Promise<any>;
  setTokenId: React.Dispatch<React.SetStateAction<string | undefined>>;
  tokenId: string | undefined;
}

// 创建Context时指定类型,默认值加错误提示
const ApiContext = React.createContext<IApiContext>({
  serviceCall: () => { throw new Error("useApi必须在APIProvider内部使用") },
  setTokenId: () => {},
  tokenId: undefined
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:48:01