Search code examples
javascriptreactjsgraphqlapollo

How to useQuery on props change with Apollo?


Currently I have a BooksList component and I'm passing down props to my BooksDetails component when a title is clicked. How do I use an Apollo hook to only query on props change?

I'm not sure how to do this using hooks. I've looked through the UseQuery documentation from Apollo. I couldn't find documentation on UseLazyQuery.

I've tried the following, but it always returns undefined:

const { loading, error, data } = useQuery(getBookQuery, {
    options: (props) => {
      return {
        variables: {
          id: props.bookId
        }
      }
    }
  })

BookList:

const BookList = () => {
  const {loading, error, data} = useQuery(getBooksQuery)
  const [selectedId, setId] = useState('');


  return (
    <div id='main'>
      <ul id='book-list'>
        {data && data.books.map(book => (
          <li onClick={() => setId(book.id)} key={book.id}>{book.name}</li>
        )) }
      </ul>
      <BookDetails bookId={selectedId} />
    </div>
  );
};

export default BookList;

BookDetails:

const BookDetails = (props) => {

  const { loading, error, data } = useQuery(getBookQuery, {
    options: (props) => {
      return {
        variables: {
          id: props.bookId
        }
      }
    }
  })

  console.log(data)
  return (
    <div id='book-details'>
      <p>Output Book Details here</p>
    </div>
  );
};

export default BookDetails;

EDIT - I forgot to add that my GetBookQuery has a parameter of ID so an example would be getBookQuery(123).


Solution

  • Use the useLazyQuery like this instead:

      const [getBook, { loading, error, data }] = useLazyQuery(getBooksQuery);
    

    Full example:

    import React from 'react';
    import { useLazyQuery } from '@apollo/react-hooks';
    
    const BookList = () => {
        const [getBook, { loading, error, data }] = useLazyQuery(getBooksQuery);
    
      return (
        <div id='main'>
          <ul id='book-list'>
            {data && data.books.map(book => (
              <li onClick={() => getBook({ variables: { id: book.id } })}} key={book.id}>{book.name}</li>
            )) }
          </ul>
          <BookDetails data={data} />
        </div>
      );
    };
    
    export default BookList;
    

    Examples and documentation can be found in Apollo's GraphQL documentation https://www.apollographql.com/docs/react/data/queries/