Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React and Axios fires twice (once undefined, once successfully)

Following the React AJAX example i have created a JSX file which purpose is to fetch and render a movie. For all i know, i am doing everything right here.

When i console.log the data in my render function i get 2 results:

  • Undefined
  • Object (which is the one i need, so this one is perfect)

How can i filter out the Undefined row without doing some if/else logic in my render function? Iterating over the result will, of course, result in an error the first time, which will crash my application.

What's the best way to handle this?

EDIT: Maybe the app gets rendered before the Axios call is done in which case i am forced to do an if/else statement?

Heres my JSX file:

import React from "react";
import axios from "axios";

export default class NetflixHero extends React.Component {
 constructor() {
    super();
    this.state = {
      movie: []
    }
 }
}

componentDidMount() {
  const apiKey = '87dfa1c669eea853da609d4968d294be';
  let requestUrl = 'https://api.themoviedb.org/3/' + this.props.apiAction + '&api_key=' + apiKey;
  axios.get(requestUrl).then(response => {
      this.setState({movie: response.data.results})
  });
}

render() {
  //Fires twice. Returns Undefined and an Object
  console.log(this.state.movie[0]);
  return(
   <div></div>
  )
}
like image 575
Michael Koelewijn Avatar asked Oct 26 '16 11:10

Michael Koelewijn


1 Answers

Check the state inside the render method. With this approach you can render a loading screen:

import React from "react";
import axios from "axios";

export default class NetflixHero extends React.Component {
 constructor() {
    super();
    this.state = {
      movie: []
    }
 }
}

componentDidMount() {
  const apiKey = '87dfa1c669eea853da609d4968d294be';
  let requestUrl = 'https://api.themoviedb.org/3/' + this.props.apiAction + '&api_key=' + apiKey;
  axios.get(requestUrl).then(response => {
      this.setState({movie: response.data.results})
  });
}

render() {
  //Loading...
  if( this.state.movie[0] === undefined ) {
      return <div>Loading...</div>
  }

  //Loaded successfully...
  return(
   <div> Movie loaded... [Do action here] </div>
  )
}

Explanation

Every time the state changes, a re-render will be triggered. The first time, your Component is constructed with this.state.movie = []. After that, componentDidMount() is triggered, which changes your state. This is triggering the render method a second time.

like image 199
dschu Avatar answered Nov 16 '22 01:11

dschu