Как получить данные из API для нескольких элементов в компоненте React JS - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь получить данные из 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;

Ответы [ 2 ]

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

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

  3. Назначьте свойство veh_data_with_count для объекта State, используя setState(), чтобы уведомить Реакцию об изменениях и разрешить ему обновлять 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

0 голосов
/ 21 января 2019

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

...