我有三种不同的数据类型:Books、Authors和Publishers。我使用react-query来获取每种类型的列表,即useBooks(bookIds)、useAuthors(authorIds)、usePublishers(publisherIds),当我尝试独立使用它们时,这非常有效。
但是,有一本书有一个authorIds和publisherIds列表,我想将Publishers和Authors对象加入到Books中。我想不出使用react-query的正确方法。理想情况下,我希望能够调用所有三个钩子,等待它们的响应,然后将其作为一个大钩子返回。然而,我不能绕着我的头去做这件事。
我尝试过的一个实现是让每个将数据连接到Book的钩子都依赖于前一个钩子的结果。这可以正常工作;但是,其中最大的问题是连接是彼此异步完成的;一旦返回数据,组件使用的数据就不能期望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的查询函数中调用所有三个钩子-查询钩子,但钩子规则不允许我这样做。
发布于 2020-10-29 08:50:21
如果不知道useBooks、useAuthors和usePublishers钩子在内部是如何工作的,我就不能准确地回答这个问题,但是我会通过编写一个执行所有useBooks调用的函数来解决这个问题,然后用useQuery包装这个函数。您不希望有条件地调用不同的钩子,因为这违反了rules of 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或未定义的。
如果你不熟悉Array.map,你可以在here上阅读它。
https://stackoverflow.com/questions/64582954
复制相似问题