I am trying to to pass down props to a react child component with information from an API, and I know the API information and all the syntax is correct because, if I don't refresh the page, all the information is there. But as soon as I Do, an error is thrown saying it "can't read property '...' undefined"
This is the parent Component:
function TeamList() {
const [URL, setURL] = useState('http://api.football-data.org/v2/teams/86/')
const [team, setTeam] = useState([])
const [teamName, setTeamName] = useState('Manchester United')
async function getTeam() {
setURL('http://api.football-data.org/v2/teams/86/')
try {
const response = await axios.get(`${URL}`, {
headers: {
'X-Auth-Token': '#'
}
})
setTeamName(response.data.name)
setTeam(response.data)
} catch (error) {
console.error(error);
}
}
useEffect(async() => {
getTeam()
}, [])
return (
<div className="Team">
<h4> {teamName} </h4>
<Team
activeComps = {team.activeCompetitions}
address = {team.address}
crest = {team.crestUrl}
email = {team.email}
founded = {team.founded}
teamID = {team.id}
tla = {team.tla}
venue = {team.venue}
website = {team.website}
squad = {team.squad}
/>
</div>
)
}
export default TeamList
This is the Child Component:
function Team(props) {
return (
<div className="Team" id={props.teamID}>
<img src={props.crest} />
<h5>Founded: {props.founded}</h5>
<h5>Current Competitions</h5>
<ul>
<li> <Link to ="/league">{props.activeComps[0].name}</Link></li>
<li> <Link to ="/league">{props.activeComps[1].name}</Link></li>
</ul>
<h5>Team Address: </h5>
<p>{props.address}</p>
<h5>Venue: </h5>
<p>{props.venue}</p>
<h5>Website: </h5>
<p>{props.website}</p>
</div>
)
}
export default Team
The first issue is that you're defaulting team
to an empty array, but it seems to be an object when it's returned from the API call. To simplify things, we can just default it to undefined
.
const [team, setTeam] = useState();
The second issue, which is causing the errors you're hitting, is that you're trying to render the Team
component before you have your data. To prevent this from happening, you can use a ternary operator to show a loading status while you're team
is undefined (note that this recommendation only really works if you take my previous recommendation):
{team ? <Team
activeComps = {team.activeCompetitions}
address = {team.address}
crest = {team.crestUrl}
email = {team.email}
founded = {team.founded}
teamID = {team.id}
tla = {team.tla}
venue = {team.venue}
website = {team.website}
squad = {team.squad}
/> : "Loading..."}
Also, I would probably recommend just passing the whole team
object down to the Team
component; that would really simplify the interface.