如何使用 Apollo 更改道具上的查询?

Posted

技术标签:

【中文标题】如何使用 Apollo 更改道具上的查询?【英文标题】:How to useQuery on props change with 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)

【问题讨论】:

只是useQuery(getBookQuery, variables: id: props.bookId ) ? apollographql.com/docs/react/data/queries/… 【参考方案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;

【讨论】:

以上是关于如何使用 Apollo 更改道具上的查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apollo GraphQL 更改查询值(其中: )

在 React 中使用 Apollo.js 将查询映射到道具

如何从 graphQL apollo 突变或查询上的 cookie 更新授权标头

Apollo 加载在道具更改时总是错误的

如何从 Apollo 缓存中查询没有 ROOT_QUERY 上的查询

如何让 QueryRenderer 传播父道具更改?