Reputation: 631
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
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
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