简体   繁体   中英

how to use async/await to allow my props to be read after state is updated (react.js)

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.

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