(React) Element type is invalid, expected a string (for built-in components) or a class/function but got

avatar
Borislav Hadzhiev

Last updated: Apr 6, 2024
5 min

banner

# (React) Element type is invalid, expected a string (for built-in components) or a class/function but got

The error "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got" occurs for multiple reasons:

  1. Mixing up default and named imports when importing a component.
  2. Forgetting to export a component from a file.
  3. Incorrectly defining a React component, e.g. as a variable instead of a function or class.
  4. Not specifying the complete path to the file that exports the component.

type-is-invalid-expected-string-but-got

To solve the error, make sure to import named exports using curly braces and default exports without and only use functions or classes as components.

# Declaring a variable that returns JSX code

Here is one example of how the error occurs.

App.js
// ๐Ÿ‘‡๏ธ Must be a function or class (NOT variable) const Button = <button>Click</button>; export default function App() { // โ›”๏ธ Warning: React.jsx: type is invalid -- expected a string // (for built-in components) or a class/function // (for composite components) but got: return ( <div> <Button /> <h1>hello world</h1> </div> ); }

The issue is that we declared a Button variable that returns JSX code.

To solve the error, we have to declare a function component instead.

App.js
// ๐Ÿ‘‡๏ธ Is now a function const Button = () => { return <button>Click</button>; }; export default function App() { return ( <div> <Button /> <h1>hello world</h1> </div> ); }

declare function component instead

The code for this article is available on GitHub

Now Button is a function that returns JSX code and can be used as a React component.

# Mixing up default and named imports and exports

Another common cause of the error is mixing up default and named imports and exports.

When a component is exported using a default export, you have to make sure to import it without using curly braces.

Header.js
// ๐Ÿ‘‡๏ธ default export export default function Header() { return <h2>Hello world</h2>; }

Now, it has to be imported without curly braces.

App.js
// ๐Ÿ‘‡๏ธ default import import Header from './Header'; export default function App() { return ( <div> <Header /> </div> ); }

using default export and import

The code for this article is available on GitHub

On the other hand, if your component is exported using a named export, it has to be imported using curly braces.

Header.js
// ๐Ÿ‘‡๏ธ named export export function Header() { return <h2>Hello world</h2>; }

Now, it has to be wrapped in curly braces when importing.

App.js
// ๐Ÿ‘‡๏ธ named import import {Header} from './Header'; export default function App() { return ( <div> <Header /> </div> ); }

Make sure you aren't exporting a component as a default export and trying to import it as a named import (wrapped in curly braces) or vice versa because this is a common cause of the error.

The examples above assume that you are importing from a file that is located in the same directory.

If you need to import from one directory up, you would do:

App.js
// ๐Ÿ‘‡๏ธ named export import {Header} from '../Header'

Similarly, to import from 2 directories up, you would do:

App.js
// ๐Ÿ‘‡๏ธ named export import {Header} from '../../Header'
The code for this article is available on GitHub

You can have multiple named exports per file, but only a single default export.

Here is an example utils.js file that has multiple named exports.

utils.js
// ๐Ÿ‘‡๏ธ named export export const sum = (a, b) => { return a + b; }; // ๐Ÿ‘‡๏ธ named export export const number = 100;

And here is how we would import the named exports in a file called App.js.

App.js
// ๐Ÿ‘‡๏ธ named imports import {sum, number} from './utils'; const App = () => { console.log(sum(number, number)); return ( <div> <h2>Result: {sum(number, number)}</h2> </div> ); }; export default App;

multiple named exports and imports

The code for this article is available on GitHub

You can have as many named exports as necessary in a file, but you can only have a single default export.

You can also mix and match. Here is an example of using a default export to export a function and a named export to export a variable.

utils.js
const sum = (a, b) => { return a + b; }; // ๐Ÿ‘‡๏ธ default export export default sum; // ๐Ÿ‘‡๏ธ named export export const number = 100;

And here is how we can import the default and named exports in a file called App.js.

App.js
// ๐Ÿ‘‡๏ธ default and named imports import sum, {number} from './utils'; const App = () => { console.log(sum(number, number)); return ( <div> <h2>Result: {sum(number, number)}</h2> </div> ); }; export default App;

We imported the sum function using a default import (no curly braces) and used a named import to import the number variable.

If the error is not resolved, try restarting your development server and your IDE.

I've written a detailed guide on using ES6 imports and exports in React.

# Specify the full path to the module you are importing from

Make sure to specify the full path to the module you are importing from.

Even if the file is called index.js, specify the name in the import statement.

App.js
import Header from './components/Header/index'

Make sure you don't have incomplete import statements.

App.js
// โ›”๏ธ incomplete import statement import Header from './components/'

The import statement ends with a forward slash and is incomplete. This often causes the error.

Instead, make sure to specify the complete path to the file that exports the component.

App.js
import Header from './components/Header/index'
The code for this article is available on GitHub

# The path that points to the module should be spelled correctly

You should also ensure that:

  1. The path that points to the module is spelled correctly.
  2. The casing is correct.
  3. The specific file exports the component.
The best way to make sure the path is correct is to delete it, start typing the path and let your IDE help you with autocomplete.

If you aren't getting autocomplete once you start typing the path, chances are your path is incorrect.

Make sure you don't mix up the ES Modules and CommonJS syntax.

You should only use the import/export syntax in your React.js app and not the module.exports or require() syntax.

# Import only from react-router-dom, not from react-router

The error also sometimes occurs when we import something from react-router instead of react-router-dom.

App.js
// โ›”๏ธ BAD // import {Link} from 'react-router'; // โœ… GOOD import {Link} from 'react-router-dom';

If you use REact Router, make sure to import from react-router-dom and not from react-router.

The code for this article is available on GitHub

# Trying to use something that is not a function or class as a component

The error also occurs when we try to use something that is not a function or class as a component.

App.js
// ๐Ÿ‘‡๏ธ must be a function or class (NOT variable) const Button = <button>Click</button>;
You should look at the error message right after got: , as it could indicate what caused the error.
App.js
// ๐Ÿ‘‡๏ธ is now a function const Button = () => { return <button>Click</button>; };

When we use a component, we have to make sure it is either a function or a class. If you use any other value as a component, the error is caused.

# Adding an import React statement to the top of your file

If none of the suggestions helped, try adding the following import statement at the top of your file.

App.js
// ๐Ÿ‘‡๏ธ add this import statement import React from 'react'; const App = () => { return ( <div> <h2>bobbyhadz.com</h2> </div> ); }; export default App;
The code for this article is available on GitHub

The import React from 'react' statement should not be necessary in recent versions of React, however, it sometimes glitches depending on your setup.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev