Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting undefined is not an object in React native when rendering

I'm new to React and React native and am trying to retrieve data from an API and then render it but I seem to be running into problems.

I can grab the data from the API alright, but when I try and render it I'm getting all sorts of errors.

Essentially all I'm trying to do is render the photos that are returned from the API. Should be simple right? Would appreciate anyone who can point me in the right track.

I'm getting errors like:

undefined is not an object (evaluating 'this.props.photos') in RenderPhotos_render

I may have jumped into React Native too early...So excuse my lack of knowledge!

var AwesomeProject = React.createClass({
    getInitialState: function() {
      return {
        isLoading: true,
        photos: this.props.photos
      };
    },
    componentWillMount: function(){
      fetch("http://localhost:3000/api/photos/", {
          method: "GET", 
          headers: {
            "x-access-token":"xxxxx",
            "x-key":"xxxx"
          },
        })
        .then((response) => response.json())
        .then((responseData) => {
            AlertIOS.alert(
                "GET Response",
                "Search Query -> " + JSON.stringify(responseData)
            )
            this.setState({
              isLoading: false
            });
            this.setState({
              photos: JSON.stringify(responseData)
            });
        })
        .done();
    },
    render: function() {
        if(this.state.isLoading){
          return <View><Text>Loading...</Text></View>
       }
        return (
            <RenderPhotos photos={this.props.photos}/>
        );
    },

});

var RenderPhotos = React.createClass({
  getInitialState: function() {
      return {
        photos: this.props.photos
      };
  },
  render: function(){
    var photos = Photos;
    return (
      <View>
        <Text> {this.props.photos[0]} </Text>
      </View>
    )
  }
});
like image 374
James111 Avatar asked Dec 27 '15 06:12

James111


People also ask

How do you deal with undefined In react native?

To check for undefined in React, use a comparison to check if the value is equal or is not equal to undefined , e.g. if (myValue === undefined) {} or if (myValue !== undefined) {} . If the condition is met, the if block will run.

What does undefined is not an object mean?

Javascript TypeError: undefined is not an object that means you're trying to treat undefined value as an Object . ( simply: trying to get data from undefined value)

What is the reason for getting error TypeError undefined is not an object in React?

The Cause. Simply, you're treating a variable like it is an object when it is not. 'undefined' means that your variable hasn't yet been defined (in this case, our object has either not been instantiated or it has been but not assigned to the variable that you are using.

Why is this undefined In React event handler?

Why is this undefined In React event handler? This is because when you use an arrow function, the event handler is automatically bound to the component instance so you don't need to bind it in the constructor. When you use an arrow function you are binding this lexically.


2 Answers

for those who dont find solution to their problems in answers above:-

This solved my problem: I changed code from

import {React} from 'react';

to

import React from 'react';

What happened is, since React is exported by default from the module so I cannot wrap it with curly-braces.

like image 199
illusionist Avatar answered Oct 17 '22 23:10

illusionist


You have two problems.

First, the prop you pass to RenderPhotos is this.props.photos, which is undefined in AwesomeProject. Looking in the render() function of RenderPhotos, you try to access the element at index 0 of this.props.photos, which is undefined. That's probably what's causing your error. I suspect you meant to set the photos prop equal to this.state.photos in the render() function of the AwesomeProject component.

Second, inside componentWillMount() of the AwesomeProject component, you make two state changes after you get photos from the API:

this.setState({
  isLoading: false
});

this.setState({
  photos: JSON.stringify(responseData)
});

It's possible, but not guaranteed, that React might batch those two setState() calls, so both state properties would be set at the same time and the render() method would be called only once. However, if these setState() functions are executed synchronously, the render() function will be called while this.state.loading === false and this.state.photos === undefined. The RenderPhotos component will mount and receive the prop photos={this.state.photos} (after making the change I described above). Unfortunately, because this.state.photos is undefined, you will encounter the same problem as above when you try to access this.props.photos[0] inside the render() function of RenderPhotos. Here's my suggestion to fix your problem:

var AwesomeProject = React.createClass({
    getInitialState: function() {
      return {
        isLoading: true,
        photos: this.props.photos
      };
    },
    componentWillMount: function(){
      fetch("http://localhost:3000/api/photos/", {
          method: "GET", 
          headers: {
            "x-access-token":"xxxxx",
            "x-key":"xxxx"
          },
        })
        .then((response) => response.json())
        .then((responseData) => {
            AlertIOS.alert(
                "GET Response",
                "Search Query -> " + JSON.stringify(responseData)
            )
            // Set both state properties at the same time to avoid passing an undefined value as a prop to RenderPhotos
            this.setState({
              isLoading: false,
              photos: JSON.stringify(responseData)
            });
        })
        .done();
    },
    render: function() {
        if(this.state.isLoading){
          return <View><Text>Loading...</Text></View>
       }
       // RenderPhotos should receive this.state.photos as a prop, not this.props.photos
        return (
            <RenderPhotos photos={this.state.photos}/>
        );
    },

});

var RenderPhotos = React.createClass({
  getInitialState: function() {
      return {
        photos: this.props.photos
      };
  },
  render: function(){
    var photos = Photos;
    return (
      <View>
        <Text> {this.props.photos[0]} </Text>
      </View>
    )
  }
});
like image 11
Brandon Avatar answered Oct 18 '22 01:10

Brandon