【问题标题】:Render array of objects in React在 React 中渲染对象数组
【发布时间】:2018-03-01 08:39:47
【问题描述】:

我在 React 组件中有一个从 API 获取一些数据的方法

this.state.matches 首先返回一个空数组

loadMatches() {
    let matches = this.state.matches;
    forEach(this.state.matchIds.splice(0,5), matchid => {
        axios.get(url)
            .then(function (response) {
                matches.push(response.data)
            })
    });
    this.setState({
        matches
    })
}

然后是一个将数据映射到 React 组件的方法

renderMatch() {
    return this.state.matches.map((match, index) => {
        return (
            <Match
                key={index}
                gameId={match.gameId}
            />
        );
    });
}

renderMatch() 在我的渲染方法中调用{this.renderMatch()} 但是没有任何东西被渲染,如果我调用 .length 它只会返回 0,即使我可以在 devtools 中看到该数组包含 5 个对象。 数组中的硬编码对象被渲染

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您正在改变状态,因此 React 不会触发新的渲染。您应该创建一个新数组而不是推入状态:

    loadMatches() {
        let promises = []; 
        forEach(this.state.matchIds.splice(0,5), matchid => {
            promises.push(axios.get(url).then(res => res.data));
        });
        Promise.all(promises).then(matches => {
            this.setState({
                matches
            });
       });
    }
    

    编辑处理异步。

    【讨论】:

      【解决方案2】:

      axios 或 fetch 是一个异步函数,因为当您调用 this.setState 时,matches 仍然是一个空数组,因此不会呈现任何内容。试试这个。你也试图直接改变状态,这是一个很大的错误。

      loadMatches() {
       let matches = this.state.matches;
      let newMatches =[];
      let requests = forEach(this.state.matchIds.splice(0,5), matchid => {
         return new Promise((resolve) => {
               axios.get(url)
                  .then(function (response) {
                     newMatches.push(response.data)
                 })
            });
          });
         Promise.all(requests).then(() => {
           this.setState({
               matches:newMatches
             }) 
      
          });
      }
      

      【讨论】:

        【解决方案3】:

        你有两个主要问题:

        第一:

        .then(function (response) {
           matches.push(response.data)
        })
        

        你不应该直接改变状态,你应该执行不可变更新。

        第二:

        this.setState({
           matches
        })
        

        您正在使用空“匹配”更新状态,此时尚未收到您的 api 调用响应。

        所以,你的实现应该是这样的:

        loadMatches() {
        let matches = this.state.matches;
        forEach(this.state.matchIds.splice(0,5), matchid => {
            axios.get(url)
                .then(function (response) {
                    const newMatch = response.data;
                    this.setState({ matches: [...matches, newMatch]});
                    matches.push(response.data)
                })
        });
        }
        

        这里有一些你也可以从阅读中受益的资源:

        https://daveceddia.com/immutable-updates-react-redux/

        https://reactjs.org/docs/state-and-lifecycle.html

        【讨论】:

          【解决方案4】:

          axios.get 是一个异步函数,它返回一个promise。就像您订购了比萨饼并试图在它交付之前吃掉它。解决承诺时需要执行setState()

          axios.get(url)
                      .then(function (response) {
                          this.setState({matches: [...matches, ...response.data]})
                         }
          

          【讨论】:

            猜你喜欢
            • 2019-11-15
            • 2023-01-13
            • 2019-03-19
            • 1970-01-01
            • 1970-01-01
            • 2015-11-16
            • 1970-01-01
            相关资源
            最近更新 更多