I'm using the most excellent react-apollo-hooks library, specifically the useQuery hook:
function Index() {
...
const [dialogOpen, setDialogOpen] = useState({ show: false, id: '0' });
...
const { data, error } = useQuery(GET_JOBS, { suspend: true });
if (error) {
return <div>Error! {error.message}</div>;
}
const jobs = data.cxJobs; //This is our data
....
function editCallback(e, more) {
setDialogOpen({ show: true, id: e });
}
....
}
Of course as soon as I change the dialogOpen state the component re-renders and the graphql query is executed again. Based on a suggestion on the library github repo I rewrote the code to set some state along with useEffect:
function Index() {
...
const [dialogOpen, setDialogOpen] = useState({ show: false, id: '0' });
const [jobs, setJobs] = useState([]);
useEffect(_=> {fetchData()}, []);
const fetchData = async _ => {
const result = await client.query({query:GET_JOBS});
setJobs(get(['data','cxJobs'], result));
}
async function onEventChanged(id, event) {
await mutateOne(client, jobGQL, eventToJob(event));
}
...
}
This is pretty good. But can I do better?
The useQuery hook will make one fetch request on initial load, and will not refetch on subsequent renders. The useQuerey hook will trigger a re-render when it receives a response from the graphql backend (whether that response is data or an error ).
The useQuery hook is the primary API for executing queries in a React application. We run a query within a React component by calling useQuery and passing it our GraphQL query string. This makes running queries from React components a breeze.
The useQuery React hook is the primary API for executing queries in an Apollo application. To run a query within a React component, call useQuery and pass it a GraphQL query string.
What is difference between useQuery and useLazyQuery? Unlike with useQuery , when you call useLazyQuery , it does not immediately execute its associated query. Instead, it returns a query function in its result tuple that you call whenever you're ready to execute the query.
You could do something like this. Also, you might also want to avoid setting the result of the query to useState and just use data directly.
const [skip, setSkip] = React.useState(false)
const { loading, data } = useQuery(QUERY, { skip })
React.useEffect(() => {
// check whether data exists
if (!loading && !!data) {
setSkip(true)
}
}, [data, loading])
@Robert, I found that you have raised this issue on apollo-hooks github. And I found that there is an answer which helped me solve this issue, hence adding it here as well so that it can help someone else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With