简体   繁体   中英

useEffect hook not setting state object properly

Ok I literally cannot figure out why this is happening. I am doing this same thing on different components and sometimes it works and sometimes it doesn't. I use the useEffect hook to get an object from my firebase storage. I get the object properly as shown in my console but I literally cannot access any nested values.

Code:

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>
)

文本

As you can the above picture shows the object logged from within the useEffect hook. I try logging it by checking is currentCampaign[0] exists. It never exists. If I do currentCampaign.body or any other top level elements, it works fine in my return statement. If I do anything nested such as currentCampaign.images[0].url -> ERROR:

I can get access to all the top level properties such as body, campaignPolicy etc. but if I do

TypeError: Cannot read property 'seconds' of undefined

If I do campaign.startDate.seconds i get same error:

TypeError: Cannot read property 'seconds' of undefined

if(currentCampaign[0]) { // Or if(campaign[0])
    console.log(currentCampaign) //this never gets logged 
}

You can't request the state value at the root level of ReviewComponent component, which means the same level of the state definition. This is called once initially when the component is rendered, so currentCampaign is always empty.

You should use this inside the useEffect with adding a state dependency.

useEffect(() => {
  if(currentCampaign[0]) {
    console.log(currentCampaign)
  }
}, [currentCampaign]);

return(
    <Typography>
       {currentCampaign.reviews[0].text}
   </Typography>

Regarding this error, currentCampaign is initially empty array, so at the first time of this component rendering, currentCampaign.reviews will be undefined. Thus currentCampaign.reviews[0].text will be the error.

You should always check currentCampaign if it is undefined or not.

FYI, currentCampaign is array in your state definition, so try to correct the syntax to request currentCampaign variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM