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