I am using useLazyQuery to get data based on primary_key (ID), which is passed to the query as variable. However, what I found is, the value that gets passed to the variable is from the previous call. (During first call nothing gets passes in variables, in second call, the value that was supposed to get passed in first call gets passes, etc...). I have tried to reproduce the phenomena using a sample GraphQL playground - https://graphqlzero.almansi.me/api) as below. Here when I click on button 'One' it is supposed to fetch post data for post id 1. For example, if I click on button 2 next, it gets data for ID 1 and so forth. It is always lagging behind 1 step. Can anybody please help figuring out what is happening here:
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>
);
CodePudding user response:
The problem is that the callback inside you onClick only has access to the value of the data variable of the last render.
After the data is received the component is rerenders and created a new instance for the onclick callback that now has access to the current data value.
If you need to access the data immediately you can either use the return value of await loadChartData
or create an effect that has data as an dependency.