updating set state in api call react

2019-08-21 00:48发布

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;

1条回答
不美不萌又怎样
2楼-- · 2019-08-21 01:10

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

查看更多
登录 后发表回答