[英]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.