简体   繁体   中英

How do I update Reactjs State with data I retrieved using a fetch API call?

I made a fetch API call in react.js and put it inside a variable defined within the function containing the fetch function. But how do I transfer this value to one of the variables in the state? I can get to the point where I console.log the variable, but still I'm not able to figure out how to update one of the state variables so that I can then display the retrieved data onto the page.

import React from 'react';

class Stock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      stockInfo: '100'
    }
  }

  componentDidMount() {
    this.fetchStock();
  }

  fetchStock() {
    const API_KEY = 'api key goes here';
    let TimeInterval = '60min';
    let StockSymbol = 'AMZN';
    let API_Call = `https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=${StockSymbol}&interval=${TimeInterval}&outputsize=compact&apikey=${API_KEY}`;
    let stockHistoryDatabase = {};
    let stockHistoryDatabaseString;

    fetch(API_Call)
      .then(
        function(response) {
          return response.json();
        }
      )
      .then(
        function(data) {
          console.log(data);

          for (var key in data['Time Series (60min)']) {
            // push the key value pair of the time stamp key and the opening value key paired together into an object with a key value pair data set storage.
            var epochKeyTime = new Date(key);
            epochKeyTime = epochKeyTime.getTime();
            stockHistoryDatabase[epochKeyTime] = data['Time Series (60min)'][key]['1. open'];
          }

          console.log(stockHistoryDatabase);
          stockHistoryDatabaseString = JSON.stringify(stockHistoryDatabase);
          console.log(stockHistoryDatabaseString);
        }
      );
  }

  handleChange = () => {
    this.setState({
      stockInfo: 'hello'
    });
  }

  render() {
    return(
      <div>
        <h1>Stocks</h1>
        <p>{this.state.stockInfo}</p>
        <button onClick={this.handleChange}>Change</button>
      </div>
    );
  }
}

export default Stock;

this is my code in entirety. I know how to change the state using a separate function that is called from a button click on the same page, but I'm unable to get the data stored in the variable 'stockHistoryDatabaseString' to replace the state 'stockInfo'.

Thank you for the help!

Since you are calling fetchStock after component is mounting. You can use arrow function as follows.

.then((data) => {
   // use data here
   this.setState({ ... }) // set you state
})

or if you are not comfortable using arrow function, then I believe you can create a function to handle the promise eg handleData

.then(this.handleData)

in class

// pseudo code

class YourClass extends React.Component {
  componentDidMount() {
    this.fetchStock()
  }
  handleData = (data) => {
    // process your data and set state
  }
  fetchStock() {
    // your API call
    fetch(API_CALL).then(this.handleData);
  }
  render() {}
}

If you are invoking fetchStock on user operation, such as button click, then you can provide appropriate context to fetchStock by binding it to React class you've created as follows:

constructor() {
  this.fetchStock = this.fetchStock.bind(this);
}

or there is another way to achieve the same (perhaps cleaner way):

fetchStock = () => {

}

First inside constructor add

this.fetchStock = this.fetchStock.bind(this);

I had a similar problem. My solution to this problem was to store this context of react class into one variable and then use it in any scope below it.

fetchStock() {
 const pointerToThis = this; // points to context of current react class
 fetch(API_Call)
  .then(function(response) {
    return response.json();
  })
  .then(function(data) {
    console.log(pointerToThis); // you can use pointerToThis which in turn points to react class 
  });
}

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