0
votes

I'm trying to make a Twitter clone using react but I'm facing the following error.

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. Check the render method of SidebarOption.

Here is my code:-

app.js

import "./styles.css";
import Sidebar from "./components/Sidebar";

export default function App() {
  return (
    <div className="App">
      <Sidebar />
    </div>
  );
}

Sidebar.js

import React from "react";
import SidebarOption from "./SidebarOption";
import HomeIcon from "@material-ui/icons/Home";
import ExploreIcon from "@material-ui/icons/Explore";
import NotificationsActiveIcon from "@material-ui/icons/NotificationsActive";
import EmailIcon from "@material-ui/icons/Email";
import BookmarksIcon from "@material-ui/icons/Bookmarks";
import ListIcon from "@material-ui/icons/List";
import AccountCircleIcon from "@material-ui/icons/AccountCircle";
import MoreHorizIcon from "@material-ui/icons/MoreHoriz";

function Sidebar() {
  return (
    <div>
      <SidebarOption Icon={HomeIcon} text="Home" />
      <SidebarOption Icon={ExploreIcon} text="Explore" />
      <SidebarOption text="Notifications" />
      <SidebarOption text="Message" />
      <SidebarOption text="Bookmarks" />
      <SidebarOption text="List" />
      <SidebarOption text="Profile" />
      <SidebarOption text="More..." />
      <SidebarOption text="Tweet" />
    </div>
  );
}

export default Sidebar;

SidebarOption.js

function SidebarOption({ text, Icon }) {
  return (
    <div>
      <Icon />
      <h2>{text}</h2>
    </div>
  );
}

export default SidebarOption;
3
What is the <Icon /> / ExploreIcon, if it's passed in as a component surely you'd need { Icon } instead?DBS

3 Answers

1
votes

You have to pass your Icon component and use like this

  <SidebarOption Icon={<ExploreIcon></ExploreIcon>} text="Explore" />
function SidebarOption({ text, Icon }) {
  return (
    <div>
       {Icon}
      <h2>{text}</h2>
    </div>
  );
}

export default SidebarOption;
1
votes

You're not passing the Icon prop to the below ones but you're expecting to render it inside SidebarOption. You can add an additional check for whether Icon is undefined or not and based on it render the same inside SidebarOption. :-

      <SidebarOption text="Home" /><HomeIcon/>
      <SidebarOption text="Notifications" />
      <SidebarOption text="Message" />
      <SidebarOption text="Bookmarks" />
      <SidebarOption text="List" />
      <SidebarOption text="Profile" />
      <SidebarOption text="More..." />
      <SidebarOption text="Tweet" />

Edit - The answer by @Vo Quoc Thang should also work because their even if you don't pass Icon prop, you're not declaring it as a component in your SidebarOption but just a normal prop. For Icon value being undefined, it simply won't render.

0
votes

You have to check if Icon is defined before using it:

import React from "react";

function SidebarOption({ text, Icon }) {
  return (
    <div>
      {Icon && <Icon />}
      <h2>{text}</h2>
    </div>
  );
}

export default SidebarOption;