API занимает слишком много времени, функция map запускается до загрузки данных

#javascript #html #css #reactjs

#javascript #HTML #css #reactjs

Вопрос:

 import React, { Component } from 'react';
import {withProvider} from './TProvider'
import ThreeCardMap from './ThreeCardMap';

class Threecard extends Component {
    constructor() {
        super();

        this.state = {
            newlist: []
        }
    }


    componentDidMount(){
        this.props.getList()
        this.setState({newlist: [this.props.list]})
    }

    // componentDidUpdate() {
    //     console.log(this.state.newlist);
    // }
    render() {
        const MappedTarot = (this.state.newlist.map((list, i) => <ThreeCardMap key={i} name={list.name} meaningup={list.meaning_up} meaningdown={list.meaning_rev}/>);
        return (
            <div>
                <h1>Three Card Reading</h1>
                <div>{ MappedTarot }</div>
            </div>
        )
        }
    }
export default withProvider(Threecard);
  

Привет, я пытаюсь создать страницу, которая берет данные из API карт Таро (https://rws-cards-api.herokuapp.com/api/v1/cards/search?type=major ). К сожалению, к моменту поступления данных моя функция map уже запущена. Я прошу посмотреть, есть ли способ заставить функцию map подождать, пока данные не поступят, прежде чем она запустится. Спасибо!

Редактировать: функция getList в контексте:

  getList = () => {
        console.log('fired')
        axios.get('https://vschool-cors.herokuapp.com?url=https://rws-cards-api.herokuapp.com/api/v1/cards/search?type=major').then(response =>{
            this.setState({
                list: response.data
            })
        }).catch(error => {
            console.log(error);
        })
    }
  

Комментарии:

1. Могу ли я посмотреть, что в getList функции?

2. Конечно, добавлена функция get list

Ответ №1:

this.props.getList() является асинхронной функцией. Вы устанавливаете список сразу после этого вызова, который неверен. Вам нужно установить это в блоке getList promise then().

Ответ №2:

getList() является асинхронной функцией и обновляет данные для родительского компонента. Итак, мое решение просто отслеживает list из родительского компонента, обновлены они или нет, через getDerivedStateFromProps

 class Threecard extends Component {
  constructor() {
    super();
      this.state = {
        newlist: []
      }
    }
    
  // Set props.list to this.state.newList and watch the change to update
  static getDerivedStateFromProps(nextProps, prevState) {
    return {
      newlist: nextProps.list
    }
  }

  componentDidMount(){
    this.props.getList()
    // Removed this.setState() from here.
  }

  render() {
    const MappedTarot = (this.state.newlist.map((list, i) => <ThreeCardMap key={i} name={list.name} meaningup={list.meaning_up} meaningdown={list.meaning_rev}/>);
    return (
      <div>
          <h1>Three Card Reading</h1>
          <div>{ MappedTarot }</div>
      </div>
    )
  }
}
export default withProvider(Threecard);