alxdelgado
alxdelgado

Reputation: 37

How to fix an Invariant Violation in React?

Essentially I am getting an Invariant Violation error:

React.createElement: 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, or you might have mixed up default and named imports.

Invariant Violation: 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, or you might have mixed up default and named imports.

What I have done is gone into the index.js file and passed through my SideBar Component. When I do this, the SideBar pops on the screen without having to click the toggleButton so I know it works. However, when I pass it through the App.js class component I get these errors.

App.js file

import React from 'react';
import { BrowserRouter as Switch, Route } from 'react-router-dom';
import './App.css';

import ResumePage from './pages/resume/resume-page.component';
import NavBar from './components/nav-bar/nav-bar.component';
import HomePage from './pages/homepage/homepage.component';
import ProjectsPage from './pages/projects/projects.component';   
import FooterNav from './components/footer/footer.component';
import {SideBar} from './components/sidebar/sidebar.component'; 



class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      sideBarOpen: false
    } 
  }

  sideBarToggleClickHandler = () => {
    this.setState ((prevState) => {
      return {sideBarOpen: !prevState.sideBarOpen};
    })
  } 

  render() {
    let SideBar; 
    if (this.state.sideBarOpen) {
      SideBar = <SideBar />; // passing in the SideBar component here 
    }
    return (
      <div className="App" style={{height: '100%'}}>
        <Switch>
          <NavBar sideBarClickHandler={this.sideBarToggleClickHandler} />
          {SideBar}
          <Route exact path='/' component={HomePage} />
          <Route path='/resume' component={ResumePage} />
          <Route path='/projects' component={ProjectsPage} />
          <FooterNav />
        </Switch>
      </div>
    );
  }
}

export default App;

Functional ToggleButton component

import React from 'react'; 

import './toggleButton.styles.scss';

const ToggleButton = props => (
   <button className='toggle-button' onClick={props.click}>
       <div className='toggle-button_line' />
       <div className='toggle-button_line' />
       <div className='toggle-button_line' />
   </button>
); 

export default ToggleButton; 

The expected result will be to have the sidebar pop up when I click the toggleButton.

Upvotes: 2

Views: 3349

Answers (3)

Dupocas
Dupocas

Reputation: 21317

Components must return either jsx or null, you are returning undefined. Initialize your variable

let SideBar = null

You could also use a ternary operator to conditionally assert a value to a const like this

const Sidebar = this.state.sidebarOpen ? <Sidebar /> : null

Also SideBar from your import will conflict with let SideBar. You need to rename one of those

import { SideBar as SideBarComp } from './foo'

Or

let SideBarComp = null 

Here is a working example of your sandbox

Edit react-portfolio

Upvotes: 3

ravibagul91
ravibagul91

Reputation: 20755

Instead of storing a component into a variable, you can simply conditionally render your component,

{this.state.sideBarOpen && <SideBar />}

Demo

Upvotes: 0

ray
ray

Reputation: 27245

Sidebar is undefined if the condition isn’t met. Initialize it to null.

Upvotes: 0

Related Questions