简体   繁体   中英

updating set state in api call react

I'm having issues with setting this.setState from within my API call. If I console.log the stocks array inside the axios call the data is available in the array. It is not available outside if it.

Is the problem because this.setState is merging objects? I'm having a hard time conceptualizing what is happening here. How do I fix this problem so I can pass the contents to props?

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

import SearchBar from './components/search_bar';
import StockList from './components/StockList';
import './App.css';

class App extends Component {
constructor() {
super();

this.state = {
  stocks: [],
  term: null,
  value: ''
};

this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
}

handleChange(e) {
this.setState({
  value: e.target.value
});
}

handleClick(e) {
if(e) e.preventDefault();
this.setState({
  value: '',
  term: this.state.value
});

let term = this.state.value;
const key = 'F41ON15LGCFM4PR7';
const url = `https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=${term}&apikey=${key}`;

axios.get(axios.get(url)
.then(res => {
  let stocks = Array.from(res.data['Stock Quotes']).map((stock) => [{symbol: stock['1. symbol'], price: stock['2. price'], volume: stock['3. volume'], timestamp: stock['4. timestamp']}]);

  this.setState((state, props) => {
    return [...this.state.stocks]
  })
})
.catch(error => console.log(error))
)
}

render () {
let stocks = this.state.stocks;
const value = this.state.value;
return (
  <div className="App">
    <h1>Stock Search</h1>
    <SearchBar value={ value }
               onChange={ this.handleChange }
               onClick={ this.handleClick }/>
    <StockList stockItems={ stocks }/>
  </div>
);
}
}

export default App;

Your setState there is the issue, it's messing up the structure of your state.

this.setState((state, props) => {
    return [...this.state.stocks]
});

Should be either:

this.setState({
    // set stocks to that array you parsed from the axios response
    stocks
});

or

this.setState((state, props) => {
    return {
        ...state,
        // set stocks to that array you parsed from the axios response
        stocks
    };
});

I suggest that because you're accessing the stocks via this.state.stocks in your render

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