reactjs - useEffect 挂钩未正确设置状态对象
问题描述
好的,我真的无法弄清楚为什么会这样。我在不同的组件上做同样的事情,有时它有效,有时它不。我使用 useEffect 挂钩从我的 firebase 存储中获取对象。如控制台所示,我正确获取了对象,但实际上我无法访问任何嵌套值。
代码:
const ReviewComponent = (props) => {
const [open, setOpen] = useState(false)
const [campaigns, setCampaigns] = useState([])
const [currentCampaign, setCurrentCampaign] = useState([])
//First useEffect hook used for something else in the code
const tempDoc = []
useEffect(() => {
var docRef = db.collection("campaigns");
docRef.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
tempDoc.push({ id: doc.id, ...doc.data() })
// doc.data() is never undefined for query doc snapshots
setCampaigns(tempDoc)
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
},[]);
//Second use effect hook (THIS IS THE ONE CAUSING ISSUES)
useEffect(() => {
const docRef = db.collection("campaigns").doc(slug);
docRef.get().then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
setCurrentCampaign(doc.data())
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
},[]);
const handleOpen = () => {
setOpen(true)
};
const handleClose = () => {
setOpen(false);
};
if(currentCampaign[0]) { // Or if(campaign[0])
console.log(currentCampaign) //this never gets logged
}
return(
<Typography>
{currentCampaign.reviews[0].text} // TypeError: Cannot read property 'text' of undefined, if I do currentCampaign.reviews -> TypeError: Cannot read property 'reviews' of undefined
</Typography>
)
如您所见,上图显示了从 useEffect 挂钩中记录的对象。我尝试通过检查 currentCampaign[0] 是否存在来记录它。它永远不存在。如果我执行 currentCampaign.body 或任何其他顶级元素,它在我的 return 语句中工作正常。如果我做任何嵌套的事情,例如 currentCampaign.images[0].url -> ERROR :
我可以访问所有顶级属性,例如 body、campaignPolicy 等,但如果我这样做了
TypeError:无法读取未定义的属性“秒”
如果我做campaign.startDate.seconds 我得到同样的错误:
TypeError:无法读取未定义的属性“秒”
解决方案
if(currentCampaign[0]) { // Or if(campaign[0])
console.log(currentCampaign) //this never gets logged
}
您不能在ReviewComponent
组件的根级别请求状态值,这意味着状态定义的同一级别。这在组件渲染时最初调用一次,因此 currentCampaign 始终为空。
您应该在useEffect
添加状态依赖项的情况下使用它。
useEffect(() => {
if(currentCampaign[0]) {
console.log(currentCampaign)
}
}, [currentCampaign]);
return(
<Typography>
{currentCampaign.reviews[0].text}
</Typography>
关于这个错误,currentCampaign 最初是空数组,所以在这个组件第一次渲染时,currentCampaign.reviews 是未定义的。因此currentCampaign.reviews[0].text
将是错误。
您应该始终检查currentCampaign
它是否未定义。
仅供参考,currentCampaign
是您的状态定义中的数组,因此请尝试更正语法以请求currentCampaign
变量。