繁体   English   中英

使用异步获取 API 数据不渲染

[英]Using async to get API data does not render

我在getSubscriptions()中从 Firebase 中提取数据,它返回一个数组:

[
    {
        "price": 2000.01,
        "product_name": "Awesome product"
    },
    {
        "active": true,
        "product_name": "Other product",
        "Price": 599.99
    }
]

我正在遍历数组,我能够得到一个结果,但我无法得到这个结果来呈现。

我知道这个问题与异步有关并等待结果返回,但我一直坚持如何将这些概念应用于我的问题。

当我取消注释行useEffect(() => setActiveNotifications(active), [active]) ,引入 useState 时,调用被置于无限循环中,调用 Firebase API 无限循环。

export default function UserAccount(props) {

  const [activeNotifications, setActiveNotifications] = useState()

  function buildSubscriptions(userId) {
    getSubscriptions(userId).then(active => {
      console.log(JSON.stringify(active, null, 4))  // This returns output above 
      
      // useEffect(() => setActiveNotifications(active), [active])  // This will cause infinite loop 

      return (
        active.map(product =>
          <p key={product.product_name}>{product.product_name}</p>)  // key defined some value to not throw warning 
      )
    })
  }

  async function getSubscriptions(userId) {
    const subPtrCollection = await getUserSubs(userId)
    let a = []
    await Promise.all(subPtrCollection.map(async docId => {  // Promise.all used to execute commands in series
      const docData = await getDocData(docId.product)
      a.push(docData)
    }))
    return a

  }

  return (
    ...
    <Box>{buildSubscriptions(user.uid)}</Box>  // Not important where `user.uid` comes from 
    ...
  )
}

无限循环是因为在渲染方法中调用的方法设置了 state 并导致渲染。 尝试以下操作 1) 在更改 uid 时,请求构建 2) 当您从 api 收到保存到 state 的结果时,这会导致渲染 3) 在渲染方法中使用 Z9ED39E2EA931586B6A985A6 数据。

export default function UserAccount(props) {
  const [activeNotifications, setActiveNotifications] = useState();

  // when ever uid changes, do the build subscriptions
  useEffect(() => buildSubscriptions(user.uid), [user.uid]);

  // get subscriptions and save to state
  function buildSubscriptions(userId) {
    getSubscriptions(userId).then((active) => setActiveNotifications(active));
  }

  async function getSubscriptions(userId) {
    const subPtrCollection = await getUserSubs(userId);
    let a = [];
    await Promise.all(
      subPtrCollection.map(async (docId) => {
        // Promise.all used to execute commands in series
        const docData = await getDocData(docId.product);
        a.push(docData);
      })
    );
    return a;
  }

  return (
    <Box>
      {activeNotifications.map((product) => (
        <p key={product.product_name}>{product.product_name}</p>
      ))}
    </Box>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM