Сопоставить данные API с this.state в ReactJS - PullRequest
0 голосов
/ 26 июня 2018

Как я могу получить ниже API для отображения каждого 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 ]

0 голосов
/ 26 июня 2018

Я вижу пару проблем

Сначала вы указали, что calendarDay: [] является массивом, и в то же время вы отображаете его свойство, которое не имеет смысла

{calendarDay.rate_plan_dates.map...

Итак, как это выглядит в настоящее время array[].property всегда не определено.

Поскольку calendarDay - это массив, поэтому он не будет иметь прямого свойства rate_plans.

один из ваших комментариев

когда console.log (this.state.calendarDay) ставится после setState I получить календарный день undefined. Еще раз спасибо за помощь - любой предложения?

если вы поместите журнал сразу после установки состояния, он не будет работать должным образом, потому что state в реакции работает в асинхронном режиме.

проверить по обратному вызову -

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>)}
0 голосов
/ 26 июня 2018

Вызовите API в ComponentDidMount, а также я разделил код на основе имени плана. Надеюсь, это поможет.

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>
    );
}
}
0 голосов
/ 26 июня 2018

Вы используете вложенный массив объектов. Вот грубое решение, которое я сделал.

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>
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...