在ReactJS中使用this.state映射API数据

时间:2018-06-26 10:04:26

标签: javascript reactjs fetch

如何获取下面的 API ,以从列表中的 JSON 中显示每个daterate?我已经遍历了JSON,从中可以看到我已经正确映射了它,但是{this.state.calendarDay}在控制台中未定义,导致.map未定义。

我想念什么?

import React, { Component } from 'react';

class Rates extends Component {
    constructor(props) {
        super(props);
        this.state = {
            fetched: false,
            isLoaded: false,
            calendarDay: []
        }
    }

    componentWillMount(){
        this.setState({
          loading : true
        });

        const proxyurl = "https://cors-anywhere.herokuapp.com/";
        const url = `//apac.littlehotelier.com/api/v1/properties/chatelainevalleydirect/rates.json`;
        fetch(proxyurl + url).then(res => res.json())
        .then(res =>{
            this.setState({
                calendarDay : res.rate_plans,
                loading : true,
                fetched : true
            });
        });
    }

    render() {
        const {fetched, loading, calendarDay} = this.state;
        let content;
        if(fetched){
          content =
          <ul>
            {calendarDay.rate_plan_dates.map((dailyRates,index) => <li key={index+1}>{dailyRates.date} - ${dailyRates.rate}</li>)}
          </ul>;
        }
        else if(loading && !fetched){
            content = <p> Loading ...</p>;
        }
        else{
          content = <div/>;
        }
        return (
          <div>
            {content}
          </div>
        );
    }
}

export default Rates;

3 个答案:

答案 0 :(得分:1)

您正在使用嵌套的对象数组。这是我提出的一个粗略解决方案。

this.setState({
            calendarDay : res, // change this
            loading : true,
            fetched : true
        });

在渲染功能内

if(fetched){
      content =
        <div>
            {calendarDay.map((item, k) =>
          <div key={k} >
            {item.rate_plans.map((ratePlans, ratePlanKey)=>
                <ul key={ratePlanKey}>
                    {ratePlans.rate_plan_dates.map((dailyRates,index) => <li key={index+1}>{dailyRates.date} - ${dailyRates.rate}</li>)}
                </ul>
            )}
          </div>
            )}
        </div>
    }

答案 1 :(得分:0)

我看到的问题对

首先,您指定calendarDay: []是一个数组,同时通过它的属性进行映射,这毫无意义

{calendarDay.rate_plan_dates.map...

因此,当前看起来array[].property的状态始终是不确定的。

由于calendarDay是一个数组,因此它没有直接属性rate_plans

您的评论之一

  

console.log(this.state.calendarDay)放在setState I之后   get calendarDay是undefined。再次为您的帮助加油-任何   建议?

如果您在设置状态后立即放置日志,则该日志将无法正常工作,因为react中的state在异步模式下有效。

通过回调验证-

this.setState({
      calendarDay: res,
      loading: true,
      fetched: true
    }, () => console.log(this.state.calendarDay));

如果 它仍然是未定义的,则res.rate_plans是来自服务器的未定义。

其他情况如下 @Kamran Nazir 在他的回答中已经提到。

{calendarDay.map((item, k) => <div key={k}>
            {item
              .rate_plans
              .map((ratePlans, ratePlanKey) => <ul key={ratePlanKey}>
                {ratePlans
                  .rate_plan_dates
                  .map((dailyRates, index) => <li key={index + 1}>{dailyRates.date}
                    - ${dailyRates.rate}</li>)}
              </ul>)}
          </div>)}

答案 2 :(得分:0)

在ComponentDidMount中调用api,并且我已经根据计划名称拆分了代码。希望这会有所帮助。

class Rates extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        loading: false,
        calendarDay: []
    }
}

componentDidMount(){
    this.setState({
      loading : true
    });
            var self = this;
    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    const url = `//apac.littlehotelier.com/api/v1/properties/chatelainevalleydirect/rates.json`;
    fetch(proxyurl + url).then(res => res.json())
    .then(res =>{
     console.log(res)
        self.setState({
            calendarDay : res,
            loading : false,
        });
    });
}

render() {

    return (
      <div>
        {this.state.loading &&
            <p>Loading...</p>
        }
        {(this.state.calendarDay.length == 0 && !this.state.loading) && 
            <p>No data Available</p>
        }
        {this.state.calendarDay.length > 0 &&
            <ul>
            {this.state.calendarDay.map(function(i,index){
                return(
                <li key={index}>
                {i.rate_plans.map(function(j,index){
                  return(
                    <ul key={index}> <p>{j.name}</p>
                      {j.rate_plan_dates.map(function(dailyRates,index){
                          return(
                            <li key={index+1}>{dailyRates.date} - ${dailyRates.rate}</li>
                        )
                      })}
                    </ul>
                  )
                })}
                </li>
                )
          })
            }
          </ul>
        }
      </div>
    );
}
}