Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object

I'm just new in ReactJS and I have a problem. I can't solve it. It seems everything is all right, but still console puts me:

A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

Here's my code:

import React from 'react';
import ReactDOM from 'react-dom';
import fetch from 'isomorphic-fetch';
import Pokemon from './Pokemon';

class PokemonList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      species: [],
      fetched: false,
      loading: false,
    };
  }
  componentWillMount(){
    this.setState({
      loading : true
    });
    fetch('http://pokeapi.co/api/v2/pokemon?limit=151').then(res => res.json())
    .then(res =>{
      this.setState({
        species : res.results,
        loading : true,
        fetched : true
      });
    });
  }
  render() {
    const {fetched, loading, species} = this.state;
    let content;
    //This if seems to be the problem
    if(fetched){
      content =
      <div className="pokemon--species--list">
        {species.map((pokemon,index) => <Pokemon key={pokemon.name} id={index+1} pokemon={pokemon}/>)}
      </div>;
    }
    else if(loading && !fetched){
        content = <p> Loading ...</p>;
    }
    else{
      content = <div/>;
    }
    return (
      <div>
        {content}
      </div>
    );
  }
}

export default PokemonList;

Pokemon.js

import React from 'react';
import ReactDOM from 'react-dom';


class Pokemon extends React.Component {
  render() {
    const {pokemon, id} = this.props;
    return
      <div className="pokemon--spacies">
        <div className="pokemon--spacies--container">
          <div className="pokemon--spacies--sprite">
            <img src={`/public/sprites/${id}.png`} />
          </div>
          <div className="pokemon--spacies--name"> {pokemon.name }</div>
        </div>
      </div>;
  }
}

export default Pokemon;

Thanks for help!

like image 786
itgirl1234 Avatar asked Mar 01 '17 09:03

itgirl1234


People also ask

What is a valid React component?

The simplest way to define a component is to write a JavaScript function: function Welcome(props) { return <h1>Hello, {props. name}</h1>; } This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element.

What does React createElement() return?

createElement() Create and return a new React element of the given type. The type argument can be either a tag name string (such as 'div' or 'span' ), a React component type (a class or a function), or a React fragment type. Code written with JSX will be converted to use React.createElement() .

What is React memo()?

React Memo is a Higher Order Component (HOC) which itself wraps around a component to memoize the rendered output and skips unnecessary renderings. The component around which it's used will generate a memoized or an optimal version of it to speed up the render process.

What is React children?

The React children prop is an important concept for creating reusable components because it allows components to be constructed together. However, a common issue with using React with Typescript is figuring out which data type to use with React children since Typescript is a strongly typed library.


2 Answers

The problem is that you have multiple statements in render and hence you need to surround that within () See the below snippet. Also the ( must be on the same line as return otherwise it will be treated a return only which is basically returning nothing.

class Pokemon extends React.Component {
  render() {
    var content = <div></div>
    return (
      <div className="pokemon--spacies">
        <div className="pokemon--spacies--container">
          <div className="pokemon--spacies--sprite">
            {content}
          </div>
          <div className="pokemon--spacies--name"> Hello</div>
        </div>
      </div>
    )
  }
}
ReactDOM.render(<Pokemon/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app"></div>
like image 186
Shubham Khatri Avatar answered Oct 17 '22 16:10

Shubham Khatri


Problem is in the return statement in Pokemon component, Because when you use:

return
   <div>
     ...
   </div>

It will be treated as:

return ;    //Automatic semicolon insertion

<div>
   ...
</div>

And that means you are not returning a valid element.

Check this answer for more details about Automatic Semicolon Insertion.

Solutions:

Wither wrap all the elements by () like this:

return (
 ....
)

or put the div in the same line of return, like this:

return <div>
   ...
       </div>

Use this part it will work:

class Pokemon extends React.Component {
  render() {
    const {pokemon, id} = this.props;
    return(
      <div className="pokemon--spacies">
        <div className="pokemon--spacies--container">
          <div className="pokemon--spacies--sprite">
            <img src={`/public/sprites/${id}.png`} />
          </div>
          <div className="pokemon--spacies--name"> {pokemon.name }</div>
        </div>
      </div>);
  }
}
like image 30
Mayank Shukla Avatar answered Oct 17 '22 15:10

Mayank Shukla