Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object

Matthew C.

The Problem

There are two possible causes for this issue: A module import or export issue or trying to render something like a React component that’s not a React component.

Module Import or Export Issue

When you import a component into another component, if the component is a named export, you must import it using a named import. The same applies to default exports. If there is a mismatch, your app won’t render and you’ll get the following message on your screen:

Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object

You may also get this similar error message that provides potential solutions:

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 `App`.

This may occur if you try to import a named export variable using a default import:

MyComponent.js

export const myVariable = "hello";

MyOtherComponent.js

import myVariable from "./MyComponent";

It may also occur if you try to import a named export function using a default import:

MyComponent.js

export default function MyComponent() { return <div>MyComponent</div>; }

MyOtherComponent.js

import { MyComponent } from "./MyComponent";

React components can be broken up into separate JavaScript files by making use of JavaScript modules. The import and export statements used by React components are module features. The issue that caused the above error messages is a JavaScript issue — it’s not React-specific.

There are two types of module exports that modules (which include React components) use: default exports and named exports.

A named export uses the name of each exported item, such as a variable or a function:

export const myVariable = "hello";

You can also export multiple items in an object:

const myVariable = "hello"; const myVariable2 = "bye"; export { myVariable, myVariable2 };

The same name is used when the item is imported into another module, which would be the JavaScript file of a React component:

import { myVariable } from "./MyComponent";

You can rename the imported named export using the as keyword:

import { myVariable as variable } from "./MyComponent";

You can import multiple named exports:

import { myVariable, myVariable2 } from "./MyComponent";

You can also import all the named exports onto an object if there are many exports:

import { * as variables } from "./MyComponent";

A default export uses the default keyword. It was designed to make it easy to have a default function provided by a module. This is useful if you need to work with existing CommonJS and AMD modules, as explained in the following article: ES6 In Depth: Modules. A JavaScript file can have only one default export, but it can have many named exports.

export default function MyComponent() { return <div>MyComponent</div>; }

A default import does not use the curly brace syntax:

import MyComponent from "./MyComponent";

A default import can also be renamed easily. The above code example can be written as:

import MyComp from "./MyComponent";

However, you should avoid doing this as it can be confusing for other developers.

Named exports are useful if you want to export multiple items from a component or if you need to change the names of imports. You may need to do this if you’re importing items from different modules that have the same name. The name change is more explicit with named imports than default imports, as the as keyword must be used.

The Solution

Make sure that if you use a named export, you import it using a named import:

export const myVariable = "hello";
import { myVariable } from "./MyComponent";

The same applies to default exports and imports:

export default function MyComponent() { return <div>MyComponent</div>; }
import MyComponent from "./MyComponent";

Also, make sure that the item is exported from the correct file.

Get Started With Sentry

Get actionable, code-level insights to resolve JavaScript performance bottlenecks and errors.

  1. Create a free Sentry account

  2. Create a JavaScript project and note your DSN

  3. Grab the Sentry JavaScript SDK

<script src="https://browser.sentry-cdn.com/7.112.2/bundle.min.js"></script>
  1. Configure your DSN
Sentry.init({ dsn: 'https://<key>@sentry.io/<project>' });

Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

Share on Twitter
Bookmark this page
Ask a questionJoin the discussion

Related Answers

A better experience for your users. An easier life for your developers.

    TwitterGitHubDribbbleLinkedinDiscord
© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.