将setState反应为array,然后console.log(array)返回已填充的对象数组,但console.log(array.length)为0

时间:2019-01-09 19:48:47

标签: arrays reactjs state render

所以我按顺序从两个URL中获取一些数据,并将响应的数据保存到一个数组中,然后将setState保存到该数组中。当我console.log(dataArray)时,可以看到内容,但是console.log(dataArray.length)为0,无论我在setState语句之后还是在render方法中立即进行检查。我应该怎么做才能将状态设置为数组,然后再次渲染?谢谢!!!

Item 2

2 个答案:

答案 0 :(得分:0)

这部分代码在forEach函数中完成请求之前运行,因此arr在此处可以为空

then( ()=>{
      this.setState({dataArray:arr});
      console.log(this.state.dataArray); //log an array full of objects.
      console.log(this.state.dataArray.length);  //but here length is 0.
})

您可以为此目的使用prmoise.all

getTrainInfo=()=>{
    let arr=[];
    let data={};
    fetch('https://api-v3.mbta.com/predictions?filter[stop]=South+Station,North+Station&filter[direction_id]=0&include=vehicle&sort=departure_time')
        .then(response=>response.json())
        .then(res=> {

            let changes = res.data.map(dat => {
                data.departureTime = dat.attributes.departure_time;
                data.boardingStaus = dat.attributes.status;
                data.trainID = dat.relationships.route.data.id;
                return data;
            });

            let requests = changes.forEach(data=>{
                    return fetch('https://api-v3.mbta.com/routes/' + data.trainID)
                        .then(response2 => response2.json())
                        .then(res2 => {
                            data.destination = res2.data.attributes.direction_destinations[0];
                            arr.push(data);
                            return res2
                        })
                });

            Promise.all(requests).then((values) => {
                this.setState({dataArray:arr});
            });

        })
};

答案 1 :(得分:0)

非常感谢@aseferov !!! 因此事实证明,我必须使用Promise.all()来确保setState将在所有提取完成后更新所有数组。

        getTrainInfo=()=>{
             let arr=[];
             let data={};
         fetch('https://api-v3.mbta.com/predictions?filter[stop]=South+Station&filter[direction_id]=0&include=vehicle&sort=departure_time')
             .then(response=>response.json())
             .then(res=> {
                let changes= res.data.map(dat => {
                     data.departureTime = dat.attributes.departure_time;
                     data.trackNo=res.data[0].relationships.vehicle.data.id? res.data[0].relationships.vehicle.data.id:0;
                     data.boardingStaus = dat.attributes.status;
                     data.trainID = dat.relationships.route.data.id;
                     return 'https://api-v3.mbta.com/routes/' + data.trainID
                 });
                //let changes=['https://api-v3.mbta.com/routes/CR-Franklin','https://api-v3.mbta.com/routes/Red','https://api-v3.mbta.com/routes/Orange','https://api-v3.mbta.com/routes/Mattapan']
                 //console.log(changes); //an array of  urls
                 let requests=changes.map(change=>{return fetch(change).then(response=>response.json()).then(res=> res.data)});  //.then(response=>response.json()).then(res=> res.data)
                 //console.log(requests);
                 Promise.all(requests)
                     .then(responses=>responses.forEach(response=>{
                         console.log(response);  //returns Objects: res.data[0], res.data[1],...
                         let destination=response.attributes.direction_destinations[0];
                         data.destination=destination;
                         arr.push(data);
                     }))
                     .then(()=>{console.log(arr); this.setState({dataArray:arr}); })
             })
     };