Muhsin Karim
Muhsin Karim

Reputation: 51

render function call immediately before fetching

when I fetch Pokemon API why render Function runs 2 times, first without state update and second with the updated state? and when I call properties in render function from API I also get an error. "Cannot read property 'next' of null"

import React, { Component } from "react";
import "./index.css";
import axios from "axios";

const url = `https://pokeapi.co/api/v2/pokemon`;
console.log(url);

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

    this.state = {
      result: null,
    };

    this.whatIGet = this.whatIGet.bind(this);
  }

  whatIGet = pokemon => {
    this.setState({
      result: pokemon.data,
    });
  };

  componentDidMount() {
    axios(url)
      .then(result => this.whatIGet(result))
      .catch(error => console.log(error));
  }

  render() {
    const { result } = this.state;
    console.log("Results", result.next);
    return <div></div>
  }
}

export default App;

Upvotes: 2

Views: 78

Answers (2)

Jjagwe Dennis
Jjagwe Dennis

Reputation: 1853

Its because there are three phases of a ReactComponent i.e The Mounting Phase, The Update Phase and the Unmounting phase.

During the mounting phase the following methods are called in the specified order.

  1. Constructor
  2. getDerivedStateFromProps
  3. Render
  4. ComponentDidMount

And during the update phase. The methods below are called in the specified order.

  1. static getDerivedStateFromProps
  2. shouldComponentUpdate
  3. render
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate

How this relates to your code. During mounting, the constructor is called which sets results to null and the render method is called when results are null. Since you are fetching data in componentDidMount and setting state when results come back, this triggers an update and the render method is run again when the component updates.

Upvotes: 0

scrowler
scrowler

Reputation: 24406

When I fetch Pokemon API why render Function runs 2 times, first without state update and second with the updated state?

This happens because React re-renders the component tree when state and props change. You need to be careful with how you design your components because of this.

In your example you may want to add a loading indicator or something before your API call has completed. You'd want to set a "loading" state value in the constructor and modify it when your API call completes, but a very lightweight example using the API result state value:

  render() {
    const { result } = this.state;
    console.log("Results", result);
    if (!result) {
      return <p>Loading...</p>;
    }
    return <div></div>;
  }

This way you'll see Loading... until your API call has completed, then your divs will render. Note that you'll see the console log statement executed whenever state or props change (at least twice in your example).

when I call properties in render function from API I also get an error. "Cannot read property 'next' of null"

It's hard to say what's happening here, because you don't have a "next" prop in the code you've shared. I suspect you're trying to access the state data before it's been loaded - doing something like the above (early return before the API call is finished) should help you though.

Upvotes: 1

Related Questions