在React

时间:2018-03-01 08:39:48

标签: javascript reactjs

我在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}
            />
        );
    });
}

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

4 个答案:

答案 0 :(得分:4)

你正在改变状态,所以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
        });
   });
}

编辑处理异步。

答案 1 :(得分:0)

您有两个主要问题:

首先:

.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

答案 2 :(得分:0)

axios或fetch是一个异步函数,当你调用this.setState时,匹配仍然是一个空数组,因此没有任何渲染。试试这个。你也试图直接改变国家,这是一个很大的错误。

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 :(得分:-1)

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

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