【问题标题】:How to useQuery on props change with Apollo?如何使用 Apollo 更改道具上的查询?
【发布时间】:2020-09-04 18:47:58
【问题描述】:

目前我有一个 BooksList 组件,当单击标题时,我正在将道具传递给我的 BooksDetails 组件。如何使用 Apollo 挂钩仅查询道具更改?

我不确定如何使用钩子来做到这一点。我浏览了 Apollo 的 UseQuery 文档。我找不到有关 UseLazyQuery 的文档。

我尝试了以下方法,但它总是返回未定义:

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

书单:

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;

书籍详情:

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;

编辑 - 我忘了补充说我的 GetBookQuery 有一个 ID 参数,所以一个例子是getBookQuery(123)

【问题讨论】:

标签: javascript reactjs graphql apollo


【解决方案1】:

像这样使用useLazyQuery

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

完整示例:

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;

示例和文档可以在 Apollo 的 GraphQL 文档中找到 https://www.apollographql.com/docs/react/data/queries/

【讨论】:

  • 我遇到的问题是 onClick 将在我的BookList 组件中。我如何将查询中的数据传递给BookDetails
  • 您可以将完整的data 作为道具传递给BookDetails 组件,然后从该对象中提取您需要的信息
  • 如果我已经在使用const {loading, error, data} = useQuery(getBooksQuery),我可以为 useLazyQuery 使用哪些变量名?我可以使用const [getBook, { loading2, error2, data2 }] = useLazyQuery(getBookQuery);吗?
  • 啊,我刚刚意识到它正在解构,所以我不得不这样做:const [getBook, { loading: loading2, error: error2, data: data2 }] = useLazyQuery(getBookQuery);,我的错!我应该为变量使用更好的命名约定吗?
  • 为避免变量名冲突,您可以使用更具描述性的变量名来代替loading2,您可以使用loadingBooks 或您实际加载的任何内容。同样,data2 变为 booksData。让我知道这是否有帮助。
【解决方案2】:

我也遵循相同的示例,在这里提出了相同的问题。我尝试按照以下方式进行。这可能对某人有帮助。

BookDetails.js

function BookDetails({ bookId }) {
  const [loadDetails, { loading, error, data }] = useLazyQuery(getBook);

  useEffect(() => {
    if (bookId) {
      loadDetails({ variables: { id: bookId } });
    }
  }, [bookId, loadDetails]);

  if (!bookId) return null;
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  // for example purpose
  return <div>{JSON.stringify(data)}</div>;
}

export default BookDetails;

【讨论】:

    猜你喜欢
    • 2018-05-19
    • 2020-04-26
    • 2017-02-08
    • 2019-06-08
    • 2020-05-05
    • 2019-11-10
    • 2020-04-20
    • 2020-05-11
    • 2018-07-05
    相关资源
    最近更新 更多