Реактивный компонент не отображает результат, как ожидалось - PullRequest
2 голосов
/ 11 января 2020

У меня есть ReactComponent, который запрашивает API остальных и отображает его результат в виде таблицы HTML. В результате получается JSON в следующей форме:

{
  timestamp: ",
  message: "",
  requestId: "",
  responseData: []
}

Компонент реакции ResultTable приведен ниже, и ожидается, что он отобразит responseData, представляющий собой список. Вот проблемы, которые я вижу:

TypeError: Невозможно прочитать свойство 'map' из неопределенного

Так что похоже, что данные не извлекаются из REST API во времени оказывать. Как я могу это исправить. Пожалуйста, найдите код для компонента ниже. Заранее спасибо.

import React, { Component } from "react";
import axios from "axios";

export class ResultTable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      fetchedJson: [],
      fooBar: false
    };
  }

  handleSubmit(selectedRecipes) {
    if (!this.state.fooBar) {
      let url =
        "http://localhost:8080/ingredients/?recipes=" +
        selectedRecipes.join(",");
      console.log(url);
      axios.get(url).then(res => {
        this.setState({
          fetchedJson: res.data,
          fooBar: true
        });
      });
    }
  }

  render() {
    this.handleSubmit(this.props.recipeList);
    return (
      <div>
        <h1 align="center">Ingredients</h1>
        <table border="1" align="center">
          <tbody>
            {this.state.fetchedJson.responseData.map(function(ingredient, ingredientIndex) {
              return (
                <tr key={ingredientIndex}>
                  <td>{ingredient.name}</td>
                  <td>{ingredient.amount}</td>
                  <td>{ingredient.unit}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
}

1 Ответ

1 голос
/ 11 января 2020

Не вызывайте побочных эффектов внутри функции render. Для этого вам необходимо использовать методы жизненного цикла (или крючки для функциональных компонентов).

Также axios.get является асинхронной функцией, поэтому в своем коде вы делаете API-вызов к серверу и пытаетесь отобразить через this.state.fetchedJson.responseData, пока не получите ответ. В этом случае fetchedJson является пустым объектом и, следовательно, fetchedJson.responseData является undefined.

Этот код должен работать:

import React, { Component } from "react";
import axios from "axios";

export class ResultTable extends Component {
    constructor(props) {
        super(props);
        this.state = {
            fetchedJson: {},
            isLoaded: false
        };
    }

    componentDidMount() {
        //move side effect (API call) to componentDidMount
        this.handleSubmit(this.props.recipeList);
    };

    handleSubmit(selectedRecipes) {
        if (!this.state.isLoaded) {
            let url =
                "http://localhost:8080/ingredients/?recipes=" +
                selectedRecipes.join(",");
            axios.get(url).then(res => {
                this.setState({
                    fetchedJson: res.data,
                    isLoaded: true
                });
            });
        }
    }

    render() {
        //check that you received data before try to render it
        return this.state.isLoaded ? (
            <div>
                <h1 align="center">Ingredients</h1>
                <table border="1" align="center">
                    <tbody>
                    {this.state.fetchedJson.responseData.map(function(ingredient, ingredientIndex) {
                        return (
                            <tr key={ingredientIndex}>
                                <td>{ingredient.name}</td>
                                <td>{ingredient.amount}</td>
                                <td>{ingredient.unit}</td>
                            </tr>
                        );
                    })}
                    </tbody>
                </table>
            </div>
        ) : (
            <div>Loading...</div>
        );
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...