Reactjs useEffect获取firebase数据不工作

Reactjs useEffect获取firebase数据不工作,reactjs,firebase,google-cloud-firestore,react-hooks,Reactjs,Firebase,Google Cloud Firestore,React Hooks,好的,我使用useEffect获取firebase firestore数据。这是我的钩子代码: const [campaign, setCampaigns] = useState([]) useEffect(() => { var docRef = db.collection("campaigns").doc(slug); docRef.get().then(function(doc) { if (doc.exists) {

好的,我使用useEffect获取firebase firestore数据。这是我的钩子代码:

 const [campaign, setCampaigns] = useState([])
useEffect(() => {
    var docRef = db.collection("campaigns").doc(slug);

    docRef.get().then(function(doc) {
      if (doc.exists) {
          console.log("Document data:", doc.data());
              setCampaigns(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);
  });
  },[]);

 console.log(campaign[0].startDate.seconds) // gives the error stated below
 console.log(campaign.images[0].url)// gives the error stated below
答复是:

我可以访问所有顶级属性,如body、campaignPolicy等,但如果我访问了

TypeError:无法读取未定义的属性“秒”

如果我执行campaign.startDate.seconds,我会得到相同的错误:

TypeError:无法读取未定义的属性“秒”

完整最小代码:

const ReviewComponent = (props) => {
  const [open, setOpen] = useState(false)
  const [campaigns, setCampaigns] = useState([])
  const [currentCampaign, setCurrentCampaign] = useState([])

//First useEffect hook
  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
      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)
  }

  return(
    <Typography>
    {currentCampaign.reviews[0].text}
   </Typography>
)
const ReviewComponent=(道具)=>{
const[open,setOpen]=useState(false)
const[campaigns,setCampaigns]=useState([])
常量[currentCampaign,setCurrentCampaign]=useState([])
//首效钩
常量tempDoc=[]
useffect(()=>{
var docRef=数据库收集(“活动”);
docRef.get().then(函数(querySnapshot){
querySnapshot.forEach(函数(doc){
tempDoc.push({id:doc.id,…doc.data()})
//对于查询文档快照,doc.data()从来都不是未定义的
设置活动(临时文档)
});
})
.catch(函数(错误){
log(“获取文档时出错:”,错误);
});
},[]);
//二次使用效果挂钩
useffect(()=>{
const docRef=db.collection(“活动”).doc(slug);
docRef.get().then(函数(doc){
如果(文件存在){
log(“文档数据:”,doc.data());
setCurrentCampaign(doc.data())
}否则{
//在这种情况下,将不定义doc.data()
log(“没有这样的文档!”);
}
}).catch(函数(错误){
log(“获取文档时出错:”,错误);
});
},[]);
const handleOpen=()=>{
setOpen(真)
};
常量handleClose=()=>{
setOpen(假);
};
如果(当前活动[0]){//或如果(活动[0])
console.log(当前活动)
}
返回(
{currentCampaign.reviews[0].text}
)

活动的默认值为空数组,它是在firebase store几分钟后设置的。 因此,您应该检查活动状态中哪些是空的或有价值的

if (campaign.length == 0)
    console.log(campaign[0].startDate.seconds);

您正试图在检索数据之前访问这些数据。发生的情况如下:

//第一次渲染

  • 将状态设置为空数组
  • 使用回调声明效果,该回调将在第一次渲染后调用
  • 您试图访问一个确实未定义的值(此时数组为空),应用程序崩溃
  • //第二次渲染

    您的代码在第一次渲染时崩溃,但如果没有:

  • 您的状态现在包含您的数据
  • 您的效果将不会被调用,因为您有一个空的依赖项数组
  • 你可以使用你的数据
  • 要使代码正常工作,并且每次异步加载数据时都应该这样做,就是检查数据是否已加载

    const [campaign, setCampaigns] = useState([]);
    
    useEffect(() => {
        const docRef = db.collection("campaigns").doc(slug);
    
        docRef.get().then(function(doc) {
            if (doc.exists) {
                console.log("Document data:", doc.data());
                setCampaigns(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);
      });
    },[]);
    
    if(campaign.length > 0) { // Or if(campaign[0])
      console.log(campaign[0].startDate.seconds)
      console.log(campaign[0].images[0].url)
    }
    

    您正在尝试像对象一样访问数组。请尝试活动[0]。改为startDate.seconds。您共享的代码中似乎没有一个正在访问
    seconds
    ,因此错误不太可能来自此代码。请确保您的问题包含。我正在执行console.log(活动[0]。startDate.seconds)就在useEffect钩子下面,我得到了这个错误:TypeError:无法读取undefined的属性'startDate'。所以它是说campaign未定义,但是如果我执行console.log(campaign)它显示了我的原始帖子中提供的图片中所示的整个对象。即使我想在return语句中使用数据,它仍会抛出相同的错误。只有活动[0]。id或活动[0]。couponPrice(都是顶级属性)这样的内容才有效。任何嵌套的内容,如活动[0]。图像[0].url引发相同的错误:TypeError:无法读取UndefinedC的属性“url”您是否可以创建引发错误的最小代码库?好的,我将其添加到我的主要帖子您似乎混合了当前campain的类型,在某一点上它是一个数组,然后是一个对象。请检查您需要的类型并坚持使用它。我在re中没有看到任何未定义值的检查恩德。