簡體   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