我有三种不同的数据类型:Books
、Authors
和 Publishers
。我使用 react-query 获取每种类型的列表,即 useBooks(bookIds)
、useAuthors(authorIds)
、usePublishers(publisherIds)
和当我尝试彼此独立地使用它们时,这非常有用。
但是,一本书有一个 authorIds
和 publisherIds
的列表,我想加入 Publishers
和 Authors
Books
的对象。我无法找出使用 react 查询执行此操作的正确方法。理想情况下,我希望能够调用所有三个钩子(Hook),等待它们的响应,然后将其作为一个大钩子(Hook)返回。但是,我不能全神贯注地去做这件事。
我尝试的一个实现是让每个将数据连接到 Book
的 Hook 都依赖于前一个 Hook 的结果。这行得通;然而,最大的问题是连接是彼此异步完成的;一旦返回数据,组件使用的数据不能指望 Book
有 Author
或 Publisher
。这是一个例子:
const usePopulatedBooks = (bookIds) => {
const booksQuery = useBooks(bookIds);
const {data: books} = booksQuery;
const authorIds = [];
const publisherIds = [];
if (books) {
books.forEach(book => {
authorIds.push(book.authorId);
authorIds.push(book.publisherIds);
})
}
// Who knows when this finishes?
const {data: authors} = useAuthors(authorIds);
// Who knows when this finishes?
const {data: publishers} = usePublishers(publisherIds);
// Adds "author" and "publisher" field (if the authors/publishers array exist) to "book"
const joinedBooks = joinData(books, authors, publishers);
return {...booksQuery, data: joinedBooks};
}
有没有什么方法可以让我以一种方式编写上述逻辑,以便在所有数据都已加入之前不会返回任何内容?在我看来,我这样做的方式是在另一个 react-query Hook 的查询函数中调用所有三个 Hook ,但 Hook 规则不允许我这样做。
最佳答案
由于不知道您的 useBooks
、useAuthors
和 usePublishers
Hook 在内部如何工作,我无法准确回答,但我会接近通过编写一个执行所有 API 调用的函数,然后用 useQuery
包装那个函数来解决问题。您不想有条件地调用不同的 Hook ,因为这违反了 rules of hooks 之一。 : “不要在循环、条件或嵌套函数中调用 Hooks。”
像这样:
async function getBookDetails() {
const books = await getAllBooks();
const authorIds = books.map(x => x.authorId);
const authors = await getAuthorsForIds(authorIds);
const publisherIds = books.map(x => x.publisherId);
const publishers = await getPublishersForIds(publisherIds);
return { books, authors, publishers };
}
然后你可以像这样将它包装在一个 useQuery 中:
const result = useQuery("book-details", getBookDetails);
这假设如果任何查询都没有结果,您将得到一个空数组 []
,而不是 null 或 undefined。
如果您不熟悉 Array.map
,可以继续阅读 here .
关于javascript - 如何使用 react-query 将来自不同 react-query Hook 的数据同步连接在一起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64582954/