Как получить данные из API для нескольких элементов в компоненте React JS

Я пытаюсь получить данные из API в моем компоненте React JS. Ссылка на API. Этот API будет заполнять число каждого транспортного средства. Последний аргумент 'audi' соответствует марке автомобиля. Мне нужно получить эти данные для 64 различных транспортных средств и создать элементы динамического списка (li), но я не знаю, как это сделать. Все работает, кроме функции fetchCount.

Вот пример данных о транспортных средствах, которые импортируются из «../shared/vehicle_make_and_models», всего 64 марки автомобилей.

const veh_data = [
{ "alfa-romeo": ["145", "90", "Alfa 6", "Alfasud"] },
{ "aston-martin": ["15", "2-Litre", "AM Vantage", "Atom", "Cygnet", "DB2"]},
{ "audi": ["100", "200", "A1", "A2", "A3", "A4", "A5", "A6", "A7"] }
];

Вот мой код:

import React, { Component } from 'react';
import { veh_data } from '../shared/vehicle_make_and_models'

class ShopByMake extends Component {
constructor(props) {
    super(props);

    this.fetchCount = this.fetchCount.bind(this);

    this.state = {
        veh_data: veh_data,
    };
}

fetchCount(make) {

    fetch('https://mysterious-journey-51969.herokuapp.com/api/vehicle-make-count/' + make)
            .then(response => {
                return response.json();
            })
            .then(data => {
            let firstKey = Object.keys(data)[0],
                count = data[firstKey];
            console.log('make count' + count);
            return count;
        })
        .catch(err => console.log(err)); 
  }

render() {

    const vehicles = this.state.veh_data.reduce((acc, veh) => {
        let make = Object.keys(veh)[0]

        return {
            makes: [
                ...acc.makes,
                <li className="mt-2"><a href="#"><img src={require('../assets/images/audi-logo.jpg')} className="img-fluid logos" /><span className="ml-4 list-text">{make} ({this.fetchCount(make)})</span></a></li>
            ]
        };
    }, { makes: [] });

    return (
        <div>
            <div className="headings-div text-center text-white mt-4 mt-lg-0"><h5 className="headings">Shop By Make</h5></div>
            <div className="mt-3" id="shopbymake">
                <ul className="list-unstyled">
                    {vehicles.makes}
                </ul>
            </div>
        </div>
    );
}
}

export default ShopByMake;

person Asad Javed    schedule 21.01.2019    source источник
comment
вы пробовали: let count = data[`${make}_count`]?   -  person aviram83    schedule 21.01.2019
comment
Что не работает? какие-либо ошибки?   -  person kiranvj    schedule 21.01.2019
comment
Метод fetchCount не возвращает значение переменной count. Не могли бы вы решить это?   -  person Asad Javed    schedule 21.01.2019


Ответы (2)


  1. Для одновременного выполнения запросов вы можете использовать Promise.all()< /а>.

  2. Когда все запросы будут выполнены, отфильтруйте любые null ответы veh_data_with_count.filter(res=> res)

  3. Назначьте свойство veh_data_with_count объекту State, используя setState() для уведомления React об изменениях. и разрешить ему обновлять DOM при необходимости.

import React, { Component } from "react";
import axios from "axios";
// import { veh_data } from '../shared/vehicle_make_and_models'
const veh_data = [
  { "alfa-romeo": ["145", "90", "Alfa 6", "Alfasud"] },
  { "aston-martin": ["15", "2-Litre", "AM Vantage", "Atom", "Cygnet", "DB2"] },
  { audi: ["100", "200", "A1", "A2", "A3", "A4", "A5", "A6", "A7"] }
];
class ShopByMake extends Component {
  constructor(props) {
    super(props);
    // this.fetchCount = this.fetchCount.bind(this);
    this.state = {
      veh_data_with_count: []
    };
  }
  componentDidMount() {
    Promise.all(
      veh_data.map(async car => {
        let make = Object.keys(car)[0];

        let res = await axios
          .get(
            "https://mysterious-journey-51969.herokuapp.com/api/vehicle-make-count/" +
              make.split('-').join('')
          )
          .catch(err => console.log(err));
        if (!res || !res.data) return null;
        let firstKey = Object.keys(res.data)[0],
            count = res.data[firstKey];

        return { make, count };
      })
    )
      .then(veh_data_with_count => {
        let removeFails = veh_data_with_count.filter(res=> res)
        this.setState({ veh_data_with_count: removeFails });
      })
      .catch(err => console.log(err));
  }

  render() {
    const vehicles = this.state.veh_data_with_count.map(
      ({ make, count }, i) => {
        return (
          <li key={i} className="mt-2">
            <a href="#">
              <img src="" className="img-fluid logos" />
              <span
                onClick={() => this.fetchCount(make)}
                className="ml-4 list-text"
              >
                {make} {count}
              </span>
            </a>
          </li>
        );
      }
    );

    return (
      <div>
        <div className="headings-div text-center text-white mt-4 mt-lg-0">
          <h5 className="headings">Shop By Make</h5>
        </div>
        <div className="mt-3" id="shopbymake">
          <ul className="list-unstyled">{vehicles}</ul>
        </div>
      </div>
    );
  }
}

export default ShopByMake;

https://codesandbox.io/s/lryq5lvn4q?moduleview=1

person cantuket    schedule 21.01.2019

Вы можете создать API, который будет возвращать счетчики для всех Vehicle_make_name, а затем заполнять эти данные в соответствии с вашими потребностями.

person Ritviz Sharma    schedule 21.01.2019
comment
Да, у меня есть API, но я не могу его получить. Пожалуйста, взгляните на код - person Asad Javed; 21.01.2019
comment
Вы можете получить все модели типа автомобиля, а затем получить количество для всех моделей. - person Ritviz Sharma; 21.01.2019