正在使用setState

时间:2019-02-08 00:00:55

标签: javascript reactjs

在下面的异步函数中,我调用stationData只是为了确认是否要将对象数组传递给bartData(这是一个空数组)。附件是我正在接收的对象数组的响应。但是,当尝试使用this.state.bartData(以确认它确实具有对象数组)时,我的return函数将bartData作为未定义返回。有什么想法吗?

    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;

回复:https://imgur.com/gallery/Luk9MCX

2 个答案:

答案 0 :(得分:2)

这里有几个错误。

首先,getRoutes()使用this.bartData而不是this.state.bartData

第二,console.log中的所有对象都将转换为字符串。您可以将其更改为

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

以便能够查看实际数据。

答案 1 :(得分:0)

我无法使Bart API在codeandbox中工作,因此我不得不模拟该API ...但是,数据的结构仍然相同。

请注意,该API可以正常工作,您只需要在map数组中的objectsthis.state.bartData上解构您想要显示的属性即可。

工作示例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;