简体   繁体   中英

State is being initialized with [object Object] in setState

In the async function below, I call stationData just to confirm that I'm passing an array of objects into bartData (which is just an empty array). Attached is a response of the array of Objects that I am receiving. However, when trying to use this.state.bartData (to confirm that it does have the array of objects), my return function is returning bartData as undefined. Any ideas?

    import React from 'react';

    const bartKey = process.env.REACT_API_BART_API_KEY;

    class StationBaseRoutes extends React.Component{
        constructor(props){
        super(props);

        this.state = {
            isLoading: true,
            station: [],
            stationAbbv: 'ALL',
            destination: '',
            bartData: []
        }
    }

    componentDidMount(){
        this.getAllStationRoutes();
    }

    async getAllStationRoutes(){
        try{
            setInterval(async () => {
                const response = await fetch(`http://api.bart.gov/api/etd.aspx?cmd=etd&orig=${this.state.stationAbbv}&key=${bartKey}&json=y`);
                const jsonResponse = await response.json();
                const apiData = jsonResponse.root;
                const stationData = apiData.station;
                console.log(stationData);
                this.setState(({
                    isLoading: false,
                    bartData: stationData
                }), () => {
                    console.log(`Callback: ${this.state.bartData}`)
                })
            }, 20000)     
        } catch(error){
            console.log(error);
        }
    }

    getRoutes = () => {
        console.log(`bartData: ${this.bartData}`)
    }

    render(){
        const {station, destination} = this.state;

        return(
          <div>
              <h2>Calling get routes: {this.getRoutes()}</h2>
              <h2>Origin: {station}</h2>
              <h3>Destination: {destination}</h3>
          </div>
        )
    }
}

export default StationBaseRoutes;

Responses: https://imgur.com/gallery/Luk9MCX

There's a couple of bugs here.

First of all, getRoutes() is using this.bartData instead of this.state.bartData

Secondly, all your objects in console.log are being converted to strings. You can change it to

console.log('bartData:', this.state.bartData);

to be able to see the actual data.

I was unable to get the Bart API to work in a codesandbox, so I had to mock the API... however, the data is still structured the same.

On that note, the API is working as expected, you just need to map over the objects in the this.state.bartData array and deconstruct the properties you want to show.

Working example : https://codesandbox.io/s/031pn7w680

import map from "lodash/map";
import React, { Component, Fragment } from "react";
import { fakeAPI } from "../../api/fakeAPI";

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

    this.state = {
      isLoading: true,
      station: [],
      stationAbbv: "ALL",
      destination: "",
      bartData: []
    };

    this.getAllStationRoutes = this.getAllStationRoutes.bind(this);
  }

  componentDidMount() {
    this.getAllStationRoutes();
  }

  async getAllStationRoutes() {
    try {
      const res = await fakeAPI.get();
      const apiData = res.data.root;
      const stationData = apiData.station;

      this.setState({
        isLoading: false,
        bartData: stationData
      });
    } catch (error) {
      console.log(error);
    }
  }

  render() {
    const { bartData, isLoading } = this.state;

    return (
      <div className="app-container">
        {isLoading ? (
          <p className="t-a-c">Loading...</p>
        ) : (
          <Fragment>
            <h1 className="t-a-c">Bart Stations</h1>
            {map(bartData, ({ name, etd }) => (
              <div className="jumbotron station" key={name}>
                <h1>Origin: {name}</h1>
                {map(etd, ({ destination }) => (
                  <li key={destination}>Destination: {destination}</li>
                ))}
              </div>
            ))}
            <pre className="preview">
              <code>{JSON.stringify(bartData, null, 4)}</code>
            </pre>
          </Fragment>
        )}
      </div>
    );
  }
}

export default StationBaseRoutes;

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