A.Burdonskaya
A.Burdonskaya

Reputation: 561

Element type is invalid: undefined - Reactjs

I have the following error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of 'Screens/Enjoy.js'.

With following code:

import React, {Component, Fragment} from 'react';
import ReactDOM from 'react-dom';
import { renderToString, AMP } from 'react-amp-template'

class Enjoy extends Component {
render() {
        const { Title, Link, Carousel } = AMP;
const amppage = (
            <Fragment>
                <Title>Hello guys :)</Title>
                <Link rel="canonical" href="http://localhost" />
                    <h1>Hello World</h1>
                    <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

                    </Carousel>
            </Fragment>
        );
        return(
                amppage
              )
    }
}
export default Enjoy

I'm using "react": "15.3.1" and "react-dom": "15.3.1"

Tell me, please, what could be the matter? I looked at similar errors, but their solutions did not help me. Thanks a lot in advance!

upd: I am very sorry, I missed the render() method when I copied it in the code!

Upvotes: 0

Views: 2080

Answers (2)

Manu
Manu

Reputation: 10934

You cannot put constants declarations inside a class body. Either move constants outside the class or define the property as a class property as I have done.

Also, the spelling of word default is wrong. Correct that as well

OPTION 1:

const amppage = (
  <Fragment>
    <Title>Hello guys :)</Title>
    <Link rel="canonical" href="http://localhost" />
    <h1>Hello World</h1>
    <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
      <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
      <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
      <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

    </Carousel>
  </Fragment>
);
class Enjoy extends Component {
    render() {
            return amppage;
    }
}
export default Enjoy;

OPTION 2:

class Enjoy extends Component {
    amppage = (
        <Fragment>
          <Title>Hello guys :)</Title>
          <Link rel="canonical" href="http://localhost" />
          <h1>Hello World</h1>
          <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
            <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
            <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
            <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

          </Carousel>
        </Fragment>
    );
    render() {
            return this.amppage;
    }
}
export default Enjoy;

Upvotes: 2

Davin Tryon
Davin Tryon

Reputation: 67296

If you are using class components, you need a render method:

class Enjoy extends Component {
    const amppage = (
            <Fragment>
                <Title>Hello guys :)</Title>
                <Link rel="canonical" href="http://localhost" />
                    <h1>Hello World</h1>
                    <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

                    </Carousel>
            </Fragment>
        );
    render() {
        return amppage;
    }
}
export default Enjoy;

However, since you are not using lifecycle methods, you can use a functional component instead:

const Enjoy = (props) => {
const amppage = (
            <Fragment>
                <Title>Hello guys :)</Title>
                <Link rel="canonical" href="http://localhost" />
                    <h1>Hello World</h1>
                    <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

                    </Carousel>
            </Fragment>
        );
        return(
                amppage
              )
}
export default Enjoy;

If you use a functional component, then you can simply return (as you were doing). Because the body of the functional component is the same as the body of the render method in class components.

There error you are seeing is telling you that when React is calling the render method, it expects a component back, but it is currently undefined because there is no body of the render.

Also, support for Fragment was not introduced until React version 16.2.0. So, on 15.x you would need to wrap in a div:

class Enjoy extends Component {
    const amppage = (
            <div>
                <Title>Hello guys :)</Title>
                <Link rel="canonical" href="http://localhost" />
                    <h1>Hello World</h1>
                    <Carousel lightbox width="400" height="300" layout="responsive" type="slides">
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>
                        <amp-img src="image.jpg" width="400" height="300" layout="responsive"></amp-img>

                    </Carousel>
            </div>
        );
    render() {
        return amppage;
    }
}
export default Enjoy;

Upvotes: 1

Related Questions