Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute react-apollo-hooks useQuery Only the First Time a Component Renders Idiomatically and Elegantly

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?

like image 856
Robert Moskal Avatar asked May 09 '19 17:05

Robert Moskal


People also ask

Does useQuery run on every render?

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 ).

How do you use useQuery in React?

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.

What is useQuery in Apollo?

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 the difference between useQuery and useLazyQuery?

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.


1 Answers

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.

like image 72
ivp Avatar answered Sep 21 '22 15:09

ivp