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

React/Apollo多组件动态调用useLazyQuery的实现问题

实现多组件独立调用查询的方案

你的核心需求是让每个组件实例拥有独立的查询状态与请求逻辑,只需利用React Hook的特性(每个组件调用Hook时会生成独立状态),结合组件props传递uuid即可实现。以下是具体实现步骤:


1. 保持Service层代码不变

你的queryIndicatorExecution Hook本身已经具备独立性,每次调用都会创建新的useLazyQuery实例,无需修改:

const QUERY_EXEUCUTE_QUERY_INDICATOR = gql`
    query executeQueryIndicator($uuid: ID!) {
        executeQueryIndicator(uuid: $uuid) {
            uuid
            messages {
                type
                text
            }
            values
        }
    }
`

export const queryIndicatorExecution = () => {
    const [executeQueryIndicator, {called, loading, data}] = useLazyQuery(
        QUERY_EXEUCUTE_QUERY_INDICATOR,{fetchPolicy: 'no-cache'}
    )

    return {executeQueryIndicator, called, loading, data}
}

2. 改造子组件,接收uuid并独立执行查询

将子组件改为接收uuid作为props,并在组件内部根据自身uuid触发查询,每个组件实例会维护自己的loading、data状态:

import { useEffect } from 'react';
import { queryIndicatorExecution } from './path-to-your-service';

const IndicatorCard = ({ uuid }) => {
  const { executeQueryIndicator, called, loading, data } = queryIndicatorExecution();

  // 组件挂载/ uuid变化时自动执行查询
  useEffect(() => {
    executeQueryIndicator({ variables: { uuid } });
  }, [uuid, executeQueryIndicator]);

  // 状态渲染逻辑
  if (loading) return <div>加载中...</div>;
  if (!called || !data) return <div>未查询</div>;

  const indicatorData = data.executeQueryIndicator;
  return (
    <div className="indicator-card">
      <h4>指标ID: {indicatorData.uuid}</h4>
      <div className="messages">
        {indicatorData.messages.map((msg, idx) => (
          <p key={idx} className={`msg-${msg.type}`}>{msg.text}</p>
        ))}
      </div>
      <div className="values">数值: {indicatorData.values.join(', ')}</div>
    </div>
  );
};

export default IndicatorCard;

如果需要手动触发查询(比如点击按钮),可以去掉useEffect,改为按钮触发:

const IndicatorCard = ({ uuid }) => {
  const { executeQueryIndicator, called, loading, data } = queryIndicatorExecution();

  return (
    <div className="indicator-card">
      <button onClick={() => executeQueryIndicator({ variables: { uuid } })} disabled={loading}>
        {loading ? '查询中...' : '执行查询'}
      </button>
      {loading && <div>加载中...</div>}
      {data && (
        <>
          <h4>指标ID: {data.executeQueryIndicator.uuid}</h4>
          {/* 渲染数据逻辑 */}
        </>
      )}
    </div>
  );
};

3. 父组件动态渲染多实例

在父组件中传入不同的uuid,渲染多个独立的子组件:

import IndicatorCard from './IndicatorCard';

const IndicatorListPage = () => {
  // 假设这是从接口或状态中获取的uuid列表
  const indicatorUuids = ['uuid1', 'uuid2', 'uuid3', 'uuid4'];

  return (
    <div className="indicator-list">
      {indicatorUuids.map(uuid => (
        <IndicatorCard key={uuid} uuid={uuid} />
      ))}
    </div>
  );
};

export default IndicatorListPage;

关键原理

React Hook的特性保证了:每个IndicatorCard组件实例调用queryIndicatorExecution时,都会创建独立的useLazyQuery状态(包括loading、data、executeQueryIndicator方法),因此多个组件之间的查询状态完全隔离,不会互相干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:12:49