Echo
Echo

Reputation: 631

How to pass on data that are fetched from Firestore as props to a component

I am fetching data from Cloud Firestore with this code

const [profile, setProfile] = useState({});
useEffect(() => {
  const fetchDoc = async() => {
    const response = await db.collection("users").doc(id).get();
    const data = response.data();
    setProfile({...data});
  }
  fetchDoc();
}, []);

This saves an object to the state that looks like this

{
  name: 'sample name',
  tertiary: {
    name: ['sample 1', 'sample 2', ...]
  },
  ...
}

The first time the page mounts, console.log(profile) returns an empty object. But then, as from what I know, useEffect triggers after this mounting, and fetches the data. Afterwards, console.log(profile) now returns the object fetched.

Now, for some reason, when I pass profile.tertiary.name as props to a component, I get an error that says it is undefined. This happens every time the page first mounts, and useEffect doesn't do anything afterwards.

<CustomBioList education={profile.tertiary.name} />

In the <CustomBioList /> component, I'm simpy trying to console.log(props) to check whether it gets the data. Am I fetching the data in a wrong way? I don't grasp the full concept of useEffect.

Upvotes: 2

Views: 412

Answers (2)

Shyam Mittal
Shyam Mittal

Reputation: 353

Whenever we pass data to props which is not defined, as in your case, the data (profile) initially is {} and hence when the component mounts the first time it passes the prop as profile.tertiary.name which should be undefined because the useEffect is yet yo run.

Better way would be something like this:

<CustomBioList education={profile && profile.tertiary && profile.tertiary.name} />

which is nothing but, making sure that profile has an object tertiary.


Other solution could be, of rendering the component only if it having some value, something like this:

(!!profile && !!profile.tertiary && <CustomBioList education={profile.tertiary.name} />)

Upvotes: 1

tmwilliamlin168
tmwilliamlin168

Reputation: 571

profile.tertiary is initially undefined, so trying to access profile.tertiary.name will throw an error.

You could add a check by replacing <CustomBioList education={profile.tertiary.name} /> with (profile.tertiary ? <CustomBioList education={profile.tertiary.name} /> : <span>Loading...</span> or something similar.

Upvotes: 2

Related Questions