Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object
Matthew C.
—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.
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.
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.
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,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.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.