Element type is invalid: expected a string (for built-in components) or a class/function React Error

14,391

ES6 Class declarations are not hoisted.

In your second line when you defined var jsx = [<Qrscan />];, that element is actually undefined. When I print out the contents of the jsx array, I get:

Object {$$typeof: Symbol(react.element), type: undefined, key: null, ref: null, props: Object…}

So you simply have to shift that jsx array declaration to after your <Qrscan> component declaration.

Refer to the following JSFiddle for the fix and see for yourself that it works after shifting the declaration order (:

var pages = ['Qrscan'];

//Rendering
class Menu extends React.Component {
    render() {
        return (
            <div id="root">
                <Header />
                <div className="container">
                    <But target="Qrscan" class="button button-QR" text="Use QR code" type="button" linkTo="" />
                    <But class="button button-URL" text="Use URL" type="button" />
                </div>
            </div>
        )
    }
}

class App extends React.Component {
    constructor (props) {
        super(props);
        this.state = {target: <Menu />};
        App.changePage = App.changePage.bind(this);
    }

    static changePage (tar) {
       this.setState({target: tar});
    }

    render () {
        return (
          this.state.target
        )
    }
}

class Qrscan extends React.Component {
    render() {
        return (
            <h1>test</h1>
        )
    }
}

var jsx = [<Qrscan />];

//elements
class Header extends React.Component {
    render () {
        return (
            <div className="header">
                <div className="header-logo">Jukey</div>
            </div>
        )
    }
}

class But extends React.Component {
    getInfo () {
        for (var i = 0; i < pages.length; i++) {
            if (pages[i] == this.props.target) {
                return jsx[i];
            }
        }
    }

    render () {
        return (
            <button onClick={() => App.changePage(this.getInfo())} className={this.props.class}>{this.props.text}</button>
        )
    }
}

ReactDOM.render (<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app">
</div>
Share:
14,391
Rick Grendel
Author by

Rick Grendel

Updated on June 25, 2022

Comments

  • Rick Grendel
    Rick Grendel almost 2 years

    I have a problem with React when I try to change the page through the button (but) the console gives me:

    Element type is invalid: expected a string (for built-in components) or >a class/function (for composite components) but got: undefined. You >likely forgot to export your component from the file it's defined in.

    But when I put the onClick code in the class code it shows the jsx code. So it works but why do I still get the error? Here is my code:

    import React from 'react';
    import {render} from 'react-dom';
    
    //sass
    require('../sass/style.scss');
    
    var pages = ['Qrscan'];
    var jsx = [<Qrscan />];
    
    class App extends React.Component {
        constructor (props) {
            super(props);
            this.state = {target: <Menu />};
            App.changePage = App.changePage.bind(this);
        }
    
        static changePage (tar) {
           this.setState({target: tar});
        }
    
        render () {
            return (
              this.state.target
            )
        }
    }
    
    
    //Rendering
    class Menu extends React.Component {
        render() {
            return (
                <div id="root">
                    <Header />
                    <div className="container">
                        <But target="Qrscan" class="button button-QR" text="Use QR code" type="button" linkTo="" />
                        <But class="button button-URL" text="Use URL" type="button" />
                    </div>
                </div>
            )
        }
    }
    
    class Qrscan extends React.Component {
        render() {
            return (
                <h1>test</h1>
            )
        }
    }
    
    //elements
    class Header extends React.Component {
        render () {
            return (
                <div className="header">
                    <div className="header-logo">Jukey</div>
                </div>
            )
        }
    }
    
    class But extends React.Component {
        getInfo () {
            for (var i = 0; i < pages.length; i++) {
                if(pages[i] == this.props.target) {
                    return jsx[i];
                }
            }
        }
    
        render () {
            return (
                <button onClick={() => App.changePage(this.getInfo())} className={this.props.class}>{this.props.text}</button>
            )
        }
    }
    
    render (<App />, document.getElementById('app'));
    

    Thank you for taking the time to help me with my problems!