首页 > 解决方案 > 在调用渲染函数之前等待信息添加到我的状态?

问题描述

我想要一些关于如何以一种允许我data在初始页面加载时以我的状态显示数组中的信息的方式重组/更改以下代码的建议。

    async componentDidMount() {
        const { id } = this.props.match.params
        const soccerApi = axios.create({
          baseURL: 'https://soccer.sportmonks.com/api/v2.0',
          params: { api_token: API }
        });
        const leagueResponse = await soccerApi.get(`leagues/${id}`)
        const standingsResponse = await soccerApi.get(`standings/season/${leagueResponse.data.data.current_season_id}`)

        const leagueInfo = {
            leagueName: leagueResponse.data.data.name,
            leagueLogo: leagueResponse.data.data.logo_path,
            standings: standingsResponse.data.data[0].standings.data
        }
        this.setState({
            data:[...this.state.data, leagueInfo]
        })
    }

目前,当尝试显示data页面首次加载时存储的信息时,我收到错误消息cannot read property 'leagueName' of undefined,尽管能够console.log(this.state.data[0].leagueName)使用我页面上的按钮成功获取此信息。
这让我相信我最初无法显示信息的原因是因为我的状态没有及时更新。

编辑:根据要求的完整组件代码;

class League extends Component {
    constructor(props) {
        super(props)
        this.state = {
            data: []
        }
    }

    async componentDidMount() {
        const { id } = this.props.match.params
        const soccerApi = axios.create({
          baseURL: 'https://soccer.sportmonks.com/api/v2.0',
          params: { api_token: API }
        });
        const leagueResponse = await soccerApi.get(`leagues/${id}`)
        const standingsResponse = await soccerApi.get(`standings/season/${leagueResponse.data.data.current_season_id}`)

        const leagueInfo = {
            leagueName: leagueResponse.data.data.name,
            leagueLogo: leagueResponse.data.data.logo_path,
            standings: standingsResponse.data.data[0].standings.data
        }
        this.setState({
            data: [...this.state.data, leagueInfo]
        })
    }


    render() { 
        return ( 
            <div>
                <h1>League Page</h1>
                <p>{this.state.data[0].leagueName}</p>

                <table className="table-auto">
                    <thead>
                        <tr>
                            <th className="p-2">Position</th>
                            <th className="p-2">Club</th>
                            <th className="p-2">Played</th>
                            <th className="p-2">Won</th>
                            <th className="p-2">Drawn</th>
                            <th className="p-2">Lost</th>
                            <th className="p-2">GF</th>
                            <th className="p-2">GA</th>
                            <th className="p-2">GD</th>
                            <th className="p-2">Points</th>
                            <th className="p-2">Form</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.data[0].standings.map(club => (
                        <tr>
                            <th className="p-2">{club.position}</th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                            <th></th>
                        </tr>
                        ))}
                    </tbody>
                </table>
            </div>
         );
    }
}

export default League;

标签: javascriptreactjsasync-await

解决方案


它看起来好像你从来没有在 UI 中映射过你的数据,所以它是一个简化的组件。

  • state 中的初始数据为空
  • 不要将状态更新为数组
  • 如果数据存在,则有条件地呈现页面

联盟.jsx

class League extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null,
    };
  }

  async componentDidMount() {
    const { id } = this.props.match.params;
    const soccerApi = axios.create({
      baseURL: "https://soccer.sportmonks.com/api/v2.0",
      params: { api_token: API }
    });
    const leagueResponse = await soccerApi.get(`leagues/${id}`);
    const standingsResponse = await soccerApi.get(
      `standings/season/${leagueResponse.data.data.current_season_id}`
    );

    const leagueInfo = {
      leagueName: leagueResponse.data.data.name,
      leagueLogo: leagueResponse.data.data.logo_path,
      standings: standingsResponse.data.data[0].standings.data
    };
    this.setState({
      data: leagueInfo,
    });
  }

  render() {
    const { data } = this.state;
    return data ? (
      <div>
        <h1>League Page</h1>
        <p>{data.leagueName}</p>

        <table className="table-auto">
          <thead>
            <tr>
              <th className="p-2">Position</th>
              <th className="p-2">Club</th>
              <th className="p-2">Played</th>
              <th className="p-2">Won</th>
              <th className="p-2">Drawn</th>
              <th className="p-2">Lost</th>
              <th className="p-2">GF</th>
              <th className="p-2">GA</th>
              <th className="p-2">GD</th>
              <th className="p-2">Points</th>
              <th className="p-2">Form</th>
            </tr>
          </thead>
          <tbody>
            {data.standings.map(club => (
              <tr>
                <th className="p-2">{club.position}</th>
                <th />
                <th />
                <th />
                <th />
                <th />
                <th />
                <th />
                <th />
                <th />
                <th />
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    ) : null;
  }
}

export default League;

如果您想渲染一些UI,那么您也可以有条件地渲染页面的特定部分。


推荐阅读