【问题标题】:Async function inside useMemo not workinguseMemo 中的异步函数不起作用
【发布时间】:2021-07-02 00:03:09
【问题描述】:

我有一种情况,我有一个包含所有书籍的对象,我想获取位于不同集合中的作者信息。我尝试在 useMemo 中获取数据,但我收到了一个错误,因为我猜这个 promise 没有得到解决。如何让useMemo等待作者的数据到来?

async function useAuthor(authorID:string) { 
      await firestore.collection('users').doc(authorID).get().then(doc => {
         return doc.data();
    })   
};      

  const normalizedBooks = useMemo(
    () =>
      books?.map( (book) => ({
        ...book,
        author: useAuthor(book.authorId),
      })),
    [books]
  );

【问题讨论】:

  • useAuthor 是自定义的 React 钩子吗?还是真的只是一个async 实用函数?
  • 只是一个异步函数
  • use* 命名约定仅用于实际挂钩(使用至少一个内置挂钩或由执行此操作的自定义挂钩组成的函数)。 “如何让 useMemo 等待数据来给作者?” 你不应该首先这样做。获取数据的方法是初始化一个没有(或为空)数据的状态,并在useEffect 中获取所需的数据。在获取组件期间,应显示占位符或加载指示器或类似的东西。组件的渲染不应该有任何异步阻塞。

标签: javascript reactjs firebase react-hooks


【解决方案1】:

获取远程数据应该在效果中完成:

function useAuthor(authorID:string) { 
    const [author, setAuthor] = useState(null);

    useEffect(() => {
        firestore.collection('users').doc(authorID).get().then(
            doc => setAuthor(doc.data())
        );   
    }, [authorID]);

    return author;
}

请注意,author 在第一次渲染期间将是 null,直到请求完成。您可以通过例如改进该示例添加加载和错误状态。或者你也可以使用类似react-query 的东西,它提供了开箱即用的功能:

import useQuery from 'react-query';

function getItemById(collectionID:string, itemID:string) {
    return firestore.collection(collectionID).doc(itemID).get().then(
        doc => doc.data()
    );
}

const Author = ({authorID}) => {
    const {data: author, isLoading, error} = useQuery(
        ['users', authorID], 
        getItemById
    );

    if (isLoading) return 'Loading...'

    if (error) return 'Failed to fetch author :(';

    return <p>{author.name}</p>;
}

【讨论】:

  • 当我使用带有 useEffect 的函数时,它抱怨它“渲染的钩子比上一次渲染时更多”
  • @bobypoz 那是因为你不应该那样使用它。无论如何,在您的.map() 通话期间尝试获取所有作者并不是一个好主意。根据您以后如何使用作者,您最好只将authorID 传递给执行获取和显示作者的组件。您最初是如何获得书单的?您如何使用作者?
  • 这就是我最后所做的......我将一个状态传递给一个子组件并获取了我通过状态返回给父组件的所有数据。
猜你喜欢
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2021-06-14
相关资源
最近更新 更多