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

在React类组件中调用Apollo Client Hook报错求助

解决React类组件中使用Apollo Client Hook报错的问题

错误原因

你遇到的Invalid hook call错误,核心原因是React Hooks只能在函数组件的顶层作用域,或者其他自定义Hooks内部调用,类组件不支持Hooks语法。你在类组件的componentDidMount方法里调用了基于useQuery的自定义HookuseCompanyLogo,违反了Hooks的使用规则,因此触发了该错误。

解决方案

方案一:将类组件重构为函数组件(推荐)

React官方目前更推荐函数组件+Hook的写法,重构后代码更简洁,还能直接复用你已有的useCompanyLogo自定义Hook:

import React from 'react';
import { useCompanyLogo } from '../../queries/companyLogo';

const Logo = () => {
  const { error, loading, data } = useCompanyLogo();

  // 处理加载和错误状态
  if (loading) return <div>spinner</div>;
  if (error) return <div>error!</div>;

  const imageSource = data.companyLogo[0].image.urls[0];

  return (
    <div className="logo-area">
      <a href="/">
        <img 
          src={`http://computer-313:5000${imageSource}`} 
          alt="Businex-Logo"  
          style={{width:"80px"}} 
        />
      </a>
    </div>
  );
};

export default Logo;

方案二:在类组件中使用Apollo Client的非Hook方式

如果需要保留类组件结构,可以选择以下两种实现方式:

方式1:使用Query渲染props组件

Apollo Client提供了Query组件,通过渲染props的方式在类组件中执行查询:

首先修改你的查询文件,导出COMPANY_LOGO查询:

import { useQuery, gql } from "@apollo/client";
export const COMPANY_LOGO = gql`
query CompanyLogo {
    companyLogo {
      image {
        urls(first: 1)
      }
    }
  }
`;
export const useCompanyLogo = () => {
  const { error, data, loading } = useQuery(COMPANY_LOGO);
  console.log(error, data, loading);
  return {
    error,
    data,
    loading
  }
}

然后修改类组件代码:

import React, { Component } from 'react';
import { Query } from '@apollo/client/react/components';
import { COMPANY_LOGO } from '../../queries/companyLogo';

class Logo extends Component {
  render() {
    return (
      <Query query={COMPANY_LOGO}>
        {({ loading, error, data }) => {
          if (loading) return <div>spinner</div>;
          if (error) return <div>error!</div>;

          const imageSource = data.companyLogo[0].image.urls[0];
          return (
            <div className="logo-area">
              <a href="/">
                <img 
                  src={`http://computer-313:5000${imageSource}`} 
                  alt="Businex-Logo"  
                  style={{width:"80px"}} 
                />
              </a>
            </div>
          );
        }}
      </Query>
    );
  }
}

export default Logo;
方式2:通过Apollo Client实例直接调用query方法

使用withApollo高阶组件给类组件注入Apollo Client实例,然后在componentDidMount中手动执行查询:

import React, { Component } from 'react';
import { withApollo } from '@apollo/client/react/hoc';
import { COMPANY_LOGO } from '../../queries/companyLogo';

class Logo extends Component {
  state = { logo: "", loading: true, error: null };

  componentDidMount() {
    // 通过props获取client实例,执行查询
    this.props.client.query({ query: COMPANY_LOGO })
      .then(({ data }) => {
        const imageSource = data.companyLogo[0].image.urls[0];
        this.setState({ logo: imageSource, loading: false });
      })
      .catch((error) => {
        this.setState({ error, loading: false });
      });
  }

  render() {
    const { loading, error, logo } = this.state;

    if (loading) return <div>spinner</div>;
    if (error) return <div>error!</div>;

    return (
      <div className="logo-area">
        <a href="/">
          <img 
            src={`http://computer-313:5000${logo}`} 
            alt="Businex-Logo"  
            style={{width:"80px"}} 
          />
        </a>
      </div>
    );
  }
}

// 用withApollo包裹组件,注入client实例
export default withApollo(Logo);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:19:01