Reputation: 658
I know this question has been asked already, but the various answers provided just don't seem to work in my case.
Parent component
import axios from "axios";
import { useEffect, useState } from "react";
import Child from "../../components/fragments/Child";
// Fetches data with no errors
export default function Parent() {
const [post, setPost] = useState([]);
useEffect(() => {
const fetchPost = async () => {
await axios.get("http://localhost:xxxxx").then((res) => {
setPost(res.data);
});
};
fetchPost();
}, []);
return (
<>
<Child post={post} />
</>
);
}
Child Component
export default function Child({ post }) {
return (
<>
{console.log(post)}
{/* Sometimes returns an error because axios hasn't finished fetching */}
</>
);
}
The Parent
fetches the data from server with no errors. However, when I pass the data to the Child
it sometimes throws "TypeError: Cannot read property 'post' of undefined"
. That breaks the whole application since the Child
is trying to access post
prop which is still in its initial empty array state before the data is fetched with axios
.
Something like ComponentDidMount()
does not work because the component maybe has mounted but the data is still being fetched by axios
.
What is the best way to get around this problem? How can I always have the post
data in Child
passed by the Parent
and avoid the "TypeError:..."
screen of failure when trying to access the prop?
Upvotes: 1
Views: 862
Reputation: 203333
Seems you are at some point updating the post
state to be undefined and then accessing it in the child. You can conditionally render the Child
component if post
is undefined/falsey for some reason.
export default function Parent() {
const [post, setPost] = useState([]);
useEffect(() => {
const fetchPost = async () => {
await axios.get("http://localhost:xxxxx").then((res) => {
setPost(res.data);
});
};
fetchPost();
}, []);
return post ? <Child post={post} /> : null;
}
Or defensively render null in Child
if post
prop is undefined/falsey.
export default function Child({ post }) {
return post ? (
<>
.... child post JSX
</>
) : null;
}
Or provide an initial value if post
is undefined. Note that this misses the edge case if post
prop exists and is some other falsey value (null
, 0
, false
, etc), so beware.
export default function Child({ post = [] }) {
return (
<>
.... child post JSX
</>
);
}
Upvotes: 1