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

useLazyQuery变量滞后一步问题排查求助

useLazyQuery 变量值滞后一步的问题解决

问题现象

使用useLazyQuery以ID作为变量获取数据时,出现变量值滞后一步的异常:首次调用无变量传入,第二次调用传入的是首次应传的值,以此类推。比如点击按钮'One'本应获取ID为1的文章数据,点击'Two'却获取到ID为1的数据,始终滞后一个操作。

原因分析

React的状态更新是异步的,useLazyQuery返回的data和variables属于组件状态变量。当你await loadChartData()后,虽然请求已经完成,但组件还没来得及重新渲染更新状态,当前事件回调的闭包里拿到的还是旧的data和variables值,直到下一次组件渲染才会更新为最新值。

解决方案

以下两种方式可解决该问题:

方式一:直接获取loadChartData的返回结果

loadChartData调用后会返回一个Promise,这个Promise会resolve当前请求的响应数据,你可以直接从这个Promise的结果里拿到最新数据,无需依赖组件状态里的data。

修改后的按钮点击逻辑示例:

<button
  onClick={async () => {
    console.log("Clicked: ", 1);
    const response = await loadChartData({ variables: {"index": 1 } });
    console.log("data: ", response.data, response.variables);
  }}
>
  One
</button>

方式二:用useEffect监听状态变化

如果需要在数据更新后执行后续逻辑,可以使用useEffect监听data或variables的变化,当它们更新时触发对应处理:

import './App.css'
import { gql, useLazyQuery } from "@apollo/client";
import { useEffect } from 'react';

const App = () => {
  const GET_DATA = gql`
    query GetData($index: ID!) {
      post(id: $index) {
        id
        title
        body
      }
    }
  `;

  const [loadChartData, { data, variables }] =
    useLazyQuery(GET_DATA, { fetchPolicy: "network-only" });

  useEffect(() => {
    if (data) {
      console.log("最新数据: ", data, variables);
      // 在这里处理数据更新后的逻辑
    }
  }, [data, variables]);

  return (
    <div className="App">
        <button
          onClick={() => {
            console.log("Clicked: ", 1);
            loadChartData({ variables: {"index": 1 } });
          }}
        >
          One
        </button>
        <button
          onClick={() => {
            console.log("Clicked: ", 2);
            loadChartData({ variables: {"index": 2 } });
          }}
        >
          Two
        </button>
        <button
          onClick={() => {
            console.log("Clicked: ", 3);
            loadChartData({ variables: {"index": 3 } });
          }}
        >
          Three
        </button>
      </div>
  );
};

export default App;

原复现代码

App.js

import './App.css'
import { gql, useLazyQuery } from "@apollo/client";

const App = () => {
  const GET_DATA = gql`
    query GetData($index: ID!) {
      post(id: $index) {
        id
        title
        body
      }
    }
  `;

  const [loadChartData, { data, variables }] =
    useLazyQuery(GET_DATA, { fetchPolicy: "network-only" });

  return (
    <div className="App">
        <button
          onClick={async () => {
            console.log("Clicked: ", 1);
            await loadChartData({ variables: {"index": 1 } });
            console.log("data: ", data, variables);
          }}
        >
          One
        </button>
        <button
          onClick={async () => {
            console.log("Clicked: ", 2);
            await loadChartData({ variables: {"index": 2 } });
            console.log("data: ", data, variables);
          }}
        >
          Two
        </button>
        <button
          onClick={async () => {
            console.log("Clicked: ", 3);
            await loadChartData({ variables: {"index": 3 } });
            console.log("data: ", data, variables);
          }}
        >
          Three
        </button>
      </div>
  );
};

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  HttpLink,
} from "@apollo/client";

const client = new ApolloClient({
  link: new HttpLink({
    uri: 'https://graphqlzero.almansi.me/api',
    headers: {
      "Content-Type": "application/json"
    }
  }),
  cache: new InMemoryCache(),
});

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:35:36