以下代码用于从firebase firestore获取数据并在useEffect中设置为状态“products”:
const { firebase } = useContext(FirebaseContext)
const [products, setProducts] = useState([])
const db=firebase.firestore();
useEffect(() => {
const unsubscribe = db.collection("products").onSnapshot((snapshot) => {
const newProducts = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setProducts(newProducts);
console.log( products);
});
return () => unsubscribe();
}, []);
当第一次渲染产品控制空数组时。(数据正确地从firestore获取并作为对象数组进入“newProducts”)。
在运行过程中,如果代码中发生了一些变化,服务器将重新启动,此时产品状态将正确控制。
而在刷新浏览器时,产品又被控制为空数组。
我希望“产品”状态是在useEffect的第一个工作中设置firestore的值
我来到这个状态更新渲染我的组件如下..
return
<div>
<h4>{product.name}</h4>
<p> {product.price}</p>
<p>{product.type}</p>
</div>
})
}
所有这些都没有运行,因为产品状态在初始渲染时为空...提示:这是因为setproduct()的异步特性。我如何才能使代码在这样一种方式,页面加载后,才设置的状态..我如何才能解决这个问题..?
3条答案
按热度按时间rjzwgtxy1#
这是因为组件还没有重新呈现,产品状态仍然显示以前的值,如果您想查看它的值,请在useffect之外使用它,或者在setProduct回调中记录prevState以查看它的值
像这样:
也可以使用另一个useEffect查看它的新值,如下所示:
wlzqhblo2#
将
console.log(products)
移到声明产品的useState钩子之后的右侧。react(
setState
)中的状态更新可能发生在asynchronously,因此,不能保证下一行具有更新后的状态,您真正关心的是组件呈现时的状态7lrncoxx3#
您可以基于任何状态变量(例如productLoading)有条件地呈现组件。
您可以使用useState钩子和状态变量productLoading来解决这个问题。
您可以在组件开始时将productLoading设置为true,并在设置状态products之后将其设置为false。
下面是一个如何实现这一点的示例:
这将允许仅在产品数据可用后呈现组件