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!
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.
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() .
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.
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.
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>
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>);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With