как использовать async / await, чтобы разрешить чтение моих реквизитов после обновления состояния (react.js )

#javascript #reactjs #asynchronous #async-await #react-props

#javascript #reactjs #асинхронный #асинхронный-ожидание #реагировать-реквизит

Вопрос:

Я пытаюсь передать реквизиты дочернему компоненту react с информацией из API, и я знаю, что информация API и весь синтаксис верны, потому что, если я не обновлю страницу, вся информация будет там. Но как только я это делаю, выдается ошибка, в которой говорится, что «не удается прочитать свойство ‘ …’ undefined»

Это родительский компонент:

 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
 

Это дочерний компонент:

 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
 

Комментарии:

1. Можете ли вы указать, какое свойство выдает эту ошибку? Может быть name из activeComps?

Ответ №1:

Первая проблема заключается в том, что вы по умолчанию team используете пустой массив, но, похоже, он является объектом, когда он возвращается из вызова API. Чтобы упростить ситуацию, мы можем просто установить значение по умолчанию undefined .

 const [team, setTeam] = useState();
 

Вторая проблема, которая вызывает ошибки, с которыми вы сталкиваетесь, заключается в том, что вы пытаетесь отобразить Team компонент до того, как получите свои данные. Чтобы этого не произошло, вы можете использовать тернарный оператор для отображения статуса загрузки, пока вы team не определены (обратите внимание, что эта рекомендация действительно работает, только если вы воспользуетесь моей предыдущей рекомендацией):

 {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..."}
 

Кроме того, я бы, вероятно, рекомендовал просто передать весь team объект Team компоненту; это действительно упростило бы интерфейс.