简体   繁体   中英

React doesn't render data coming from an api response

I've seen a lot of questions and I couldn't get the solution here is my code:

import React, { Component } from "react";
import axios from "axios";
import "./tree.css";
import "./mainTree";

class TablesTree extends Component {
  constructor(props) {
    super(props);
    this.data = this.props.info;
    this.state = {
      fields: [],
      data: [],
      show: false
    };
  }

  componentDidMount() {
    var dataGet = [];
    this.props.tables.forEach((name, i) => {
      this.getFieldsTable(name.TABLE_NAME, (err, res) => {
        if (res) {
          dataGet.push({
            TABLE_NAME: name.TABLE_NAME,
            columns: res
          });
        }
      });
    });
    this.setState({ data: dataGet });
  }
  getFieldsTable(table, callback) {
    axios
      .get(`table/columns?name=${this.data.user}&psw=${this.data.password}&schema=${this.data.schema}&table=${table}`)
      .then(response => {
        callback(null, response.data);
      })
      .catch(error => {
        console.log(error);
      });
  }

  render() {
    return (
      <div>
        {this.state.data
          ? this.state.data.map((itm, i) => {
              return (
                <div>
                  <h1>{itm.TABLE_NAME}</h1>
                </div>
              );
            })
          : null}
      </div>
    );
  }
}

export default TablesTree;

I've made console.log of the this.state.data and the data is in there, but it doesn't renders anything I've tried a lot of soutions, but I still without rendering the data, I will apreciate your help.

There's a few things I would change about your code, but most importantly you need to do this.setState after your push to dataGet (inside of your callback function).

Because your API call is asynchronous, you are only calling setState once when your component is initially mounted (and while dataGet is still empty).

getFieldsTable is asynchronous, so the dataGet array will be empty when you call setState .

You could return the promise from getFieldsTable and use Promise.all on all the promises, and use the data when all of them have resolved.

Example

class TablesTree extends Component {
  // ...

  componentDidMount() {
    const promises = this.props.tables.map(name => {
      return this.getFieldsTable(name.TABLE_NAME).then(res => {
        return {
          TABLE_NAME: name.TABLE_NAME,
          columns: res
        };
      });
    });

    Promise.all(promises).then(data => {
      this.setState({ data });
    });
  }

  getFieldsTable(table) {
    return axios
      .get(`table/columns?name=${this.data.user}&psw=${this.data.password}&schema=${this.data.schema}&table=${table}`)
      .then(response => {
        return response.data;
      })
      .catch(error => {
        console.log(error);
      });
  }

  // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM