简体   繁体   中英

I could display API data in my console.log, but I can't setState with it . . . how can I setState? (fetch, React Native)

constructor(props){
    super(props);
    if(myCounter.intCoin == 0){
        this.fetchCoinsAPI("litecoin", "usd");
        this.coinMet("ltc");
    }
    this.state = {
        X: new Animated.Value(0),
        data: undefined,
        arrayLength: undefined,
        line: undefined,
        dataReverse: undefined,
        properties: undefined,
        lineLength: undefined,
        color: "#CDCDCD",
        translate: new Animated.Value(-500), 
        coinColor: {
            btc: {color:"#31055A", selected:false},  
            eth: {color:"#31055A", selected:false}, 
            ltc: {color:"#31055A", selected:false},  
        },
        amountCombined: "USD 0.00",
        currency: "USD ",
        mainCurrency:"usd"
    };
    console.log(this.state.data);
}
fetchCoinsAPI(coinID, currency){
    return fetch(`https://api.coingecko.com/api/v3/coins/${coinID}/market_chart?vs_currency=${currency}&days=7`, {
        method: 'GET'
    })
    .then(res => res.json())
    .then(resp => this.setState({data: resp.prices}))
    .catch(err => {console.log(err)});
}

**I'm fetching data from a remote API for charting **
It returns undefined for the state data, but when I console.log(resp.prices) in .then() it works. I'm stumped, can someone point out what I'm missing?

Thanks, jedBoy.

There are three observations I would like to share.

Bind methods

fetchCoinsAPI uses Component.setState , so bind the context of fetchCoinsAPI to the component in the constructor

constructor(props){

    this.fetchCoinsAPI = this.fetchCoinsAPI.bind(this);

}

Do not call external sources in the constructor

Put them in componentDidMount

componentDidMount {
    this.fetchCoinsAPI("litecoin", "USD");
}

JavaScript is asynchronous

The data will not be available due to the asynchronous behavior of JavaScript. Read How do I return the response from an asynchronous call?

Convert it into an arrow function. like this

const fetchCoinsAPI = (coinID, currency) => {
    return fetch(`https://api.coingecko.com/api/v3/coins/${coinID}/market_chart?vs_currency=${currency}&days=7`, {
        method: 'GET'
    })
    .then(res => res.json())
    .then(resp => this.setState({data: resp.prices}))
    .catch(err => {console.log(err)});
}

Since you are setting the state on an async call, you can write the state-dependent code after the state is updated

...
this.setState({data: resp.prices},() => {
    // code after state is set
})
...

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