bordax
bordax

Reputation: 87

ReactJS state is being updated after an API request

I'm having an issue with React state. It receives an array of objects and it's being set properly in state, but then function finishes it shows that state is empty. Can anyone explain this behaviour?

  componentDidMount() {
    this.getWeather();
    this.getForecast();
    this.setState({location: ''});
  }

  getWeather() {
    if (this.state.location === "") {
      this.setState({error: 'Please enter something'});
    } else {
      OpenWeather.getWeather(this.state.location).then(result => {
        if (result.cod === "404") {
          this.setState({error: 'City not found'});
        } else if (result.cod === 200) {
          this.setState({error: ''});
          this.setState({weather: result});
        } else {
          this.setState({error: 'Server error'});
        }
      });
    }
  }

  getForecast() {
    OpenWeather.getForecast(this.state.location).then(forecast => {
      console.log("Returned forecast:");
      console.log(forecast);
      this.setState({forecast: forecast});
      console.log("Forecast saved to state(inside function)");
      console.log(this.state.forecast);
    });
    console.log("Forecast saved to state(outside function)");
    console.log(this.state.forecast);
  }

Console output:

Forecast saved to state(outside function)
[]
Returned forecast:
(5) [{…}, {…}, {…}, {…}, {…}]
Forecast saved to state(inside function)
(5) [{…}, {…}, {…}, {…}, {…}]

Upvotes: 2

Views: 104

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281646

There are two things, conceptually wrong.

First: Your API requests to OpenWeather. getForecast is asynchronous and hence before your API returns a response the Javascript code after it is being executed and hence you get the first response as

Forecast saved to state(outside function)
[]

Now when the Api results in Success, you get

Returned forecast:
(5) [{…}, {…}, {…}, {…}, {…}]

Second: Since setState is asynchronous, your third statement

console.log("Forecast saved to state(inside function)");
console.log(this.state.forecast);

may or may not give you the updated value. You should instead make use of setState callback.

Check these question for more info

When to use React setState callback

calling setState doesn't mutate state immediately

Upvotes: 3

Related Questions