代码之家  ›  专栏  ›  技术社区  ›  Darren

在reactjs中用this.state映射API数据

  •  2
  • Darren  · 技术社区  · 6 年前

    我怎样才能拿到下面的 美国石油学会 显示每个 date rate 来自 JSON公司 在列表中?我已经完成了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 回复  |  直到 6 年前
        1
  •  1
  •   Kamran Nazir    6 年前

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

    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>
        }
    
        2
  •  0
  •   Manoz    6 年前

    我看到的几个问题

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

    {calendarDay.rate_plan_dates.map...
    

    所以它现在看起来是什么样子的 array[].property 总是未定义。

    calendarDay 是数组,因此它将不具有直接属性 rate_plans .

    你的一条评论

    什么时候? console.log(this.state.calendarday) 位于设置状态I之后 得到日历是 undefined .再次为你的帮助干杯-任何 建议?

    如果在设置状态后立即放置日志,它将无法按预期工作,因为 state 在React中以异步模式工作。

    通过回调进行验证-

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

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

    否则按如下步骤操作 @卡姆兰·纳齐尔 他的回答中已经提到了。

    {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>)}
    
        3
  •  0
  •   Subhanshu    6 年前

    调用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>
        );
    }
    }