Pankaj Thakur
Pankaj Thakur

Reputation: 9891

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

I am getting this error:

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

This is my code:

var React = require('react')
var ReactDOM =  require('react-dom')
var Router = require('react-router')
var Route = Router.Route
var Link = Router.Link

var App = React.createClass({
  render() {
    return (
      <div>
        <h1>App</h1>
        <ul>
          <li><Link to="/about">About</Link></li>
        </ul>
      </div>
    )
  }
})

var About = require('./components/Home')
ReactDOM.render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
    </Route>
  </Router>
), document.body)

My Home.jsx file:

var React = require('react');
var RaisedButton = require('material-ui/lib/raised-button');

var Home = React.createClass({
  render:function() {
    return (
        <RaisedButton label="Default" />
    );
  },
});

module.exports = Home;

Upvotes: 848

Views: 1149669

Answers (30)

DamianoPantani
DamianoPantani

Reputation: 1376

My problem was passing string to cloneElement:

const Tooltip = ({ content }) => {
  const something = cloneElement(content, { ... });
}

// ❌ BAD
<Tooltip content="BOOM !!" />

// ✅ GOOD
<Tooltip content={<div>YAY !!</div>} />

Upvotes: 0

NSCoder
NSCoder

Reputation: 1668

If you get this error, it might be because you're importing link using

import { Link } from 'react-router'

instead, it might be better to use

import { Link } from 'react-router-dom'
                      ^--------------^

I believe this is a requirement for the react router version 4

Upvotes: 32

Yamo93
Yamo93

Reputation: 512

I got this error in a test file due to a jest.mock(moduleName, callback) at the top of the file which pointed to the module that exported the UI component used in the test. Removing the mock was the solution for me.

Upvotes: 0

Anjan Talatam
Anjan Talatam

Reputation: 3996

For Next JS

Restart your server ✅

I spent quite a lot of time debugging the issue.

I got the error when using clsx() for my className prop. The error goes away when removed clsx()

Searched for Next JS issues in clsx and vice versa. Didn't find any active/ past issues. So I just tried restarting the server, and it worked.

Upvotes: 2

Rushi Dave
Rushi Dave

Reputation: 17

I had same error in React app,during practice in my console. Answer: Check your parameters or attributes are small or capital letters.And try to change it and run again. Or may be you forget to add component module. It solved my error. Try it.

Upvotes: 0

honzzyk
honzzyk

Reputation: 187

In my case was problem with npm-workspaces. I have imported badly something from different workspace.

Upvotes: 1

wongx
wongx

Reputation: 11859

For me, it was because my component wasn't exporting for some reason using the * notation, so I had to name the export explicitly

// index.ts
export * from "./Button"

to

// index.ts
export { Button } from "./Button"

Upvotes: 4

Alexandr Chazov
Alexandr Chazov

Reputation: 19

The problem might be in using an SVG as a component.

import { ReactComponent as HeaderLogo } from "../../assets/logoHeader.svg";
    
    const Header = () => {
        return (
            <div>
                <HeaderLogo />
            </div>
        );
    };

You can display an image this way:

import HeaderLogo from "../../assets/logoHeader.svg";

const Header = () => {
    return (
        <div>
            <img src={HeaderLogo} alt="React Logo" />
        </div>
    );
};

Upvotes: 1

cshdev
cshdev

Reputation: 39

I don't believe my situation and remedy are discussed here, so I'll add.

I have a function that returns an object called notification

import IconProgress from '../assets/svg/IconProgress';

  const getNotificationFromAttachment = (attachment) => {
    const notification = {
    Icon: IconProcessing,
    iconProps: {},
  };
  
  ...
  notification.Icon = {IconProgress};
  
  return notification
}

React expects a String or Class/Function as the value for the variable notification.Icon

So all you need to do is change {IconProgress} to IconProgress

See image below:

enter image description here

Upvotes: 0

Gabriel Arghire
Gabriel Arghire

Reputation: 2360

Make sure you only return one PARENT CHILD

This will work

<div>
    <p> Something here </p>
</div>

This won't work

<div>
    <p> Something here </p>
</div>
<div>
    <p> Something else here </p>
</div>

Upvotes: 0

Dareon
Dareon

Reputation: 384

For me it was the name of app config json. In the index.js the imports were like this:

import { AppRegistry } from 'react-native'
import App from './app'
import { name as appName } from './app.json'

AppRegistry.registerComponent(appName, () => App)

React Native does not differentiate between './app' and './app.json'. No idea why. So I've changed the name of the app.json to app.config.json and this has solved the problem:

import { AppRegistry } from 'react-native'
import App from './app'
import { name as appName } from './app.config.json'

AppRegistry.registerComponent(appName, () => App)

Upvotes: 0

Kodali444
Kodali444

Reputation: 1443

In my case,

//details.js 
import React from 'react'

const Details = (props) =>{
return <h1>Details</h1>
}

export default Details;


//main.js
import React from "react";
import { withRouter } from "react-router";
import {Route,BrowserRouter as Router,Redirect,Switch,Link} from "react-router-dom";
import Details from "./myAccount/details";

const Main = (props) => {
 return (
   <>
        <Switch>
          <Route path="/my-account/details" component={<Details />} />
        </Switch>
   </>

 );
};

export default withRouter(Main);

===========================

Replaced with below one, error got fixed
component={<Details />}  with  component={Details} 

Upvotes: 0

CyberMessiah
CyberMessiah

Reputation: 1268

Under similar case, I had the same nasty error and I concentrated on the code but nothing above seemed to improve the situation. I was transferring from Javascript to Typescript but encountered that for some weird reason I had BOTH files at the same time. Removing the JS version solved it, that may save somebody's time.

Upvotes: 1

amir behrouzi
amir behrouzi

Reputation: 155

The error was fixed when I changed this code

AppRegistry.registerComponent(appName, App );

to this code :

AppRegistry.registerComponent(appName, () => App);

Upvotes: 1

bitbuoy
bitbuoy

Reputation: 393

Error? its definitely an import or export issue , you are reffering to a component or container that either you haven't exported from its defining script or when importing it u have used the wrong format.

Solution?

  1. Go through all your component/container definitions and make sure you have exported them at the end of the script i.e "export default 'yourcomponentname';" or at the beginning of the component definition i.e export const 'yourcomponentname'=() =>{ ....... }
  2. At your import statements make sure you have not mixed up named and default imports based on your corresponding export statements

Upvotes: 1

Daniel Danielecki
Daniel Danielecki

Reputation: 10502

Are you tired of naive import/export answers while you're nesting components?

Well, I've been, too, when trying to pass in props from parent to child, and the child was supposed to render sibling component.

Let say, you have a BaseDialog (parent) component, in which you want to have another component SettingsDialog (child) in which you want to render its independent component.

BaseDialog.tsx

import BaseButton from "./../BaseButton";
...
<SettingsDialog
  BaseButton={<BaseButton title="Connect Wallet" />}
/>

and you're trying to render in somewhere in Settings.Dialog.tsx the

const SettingsDialog = (props: {
  BaseButton: any;
}) => {
  const { BaseButton } = props;

  return(
    <div>
      {BaseButton}
    </div>
  );
}

(yes, it's a handy way to pass components parent->child, especially when they grow, but here it breaks), but it'll cause the Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object error.

What you can do, to fix it, and still use the BaseButton, is to simply import it separately.

Settings.Dialog.tsx

import BaseButton from "./../BaseButton";

const SettingsDialog = () => {
  return(
    <div>
      <BaseButton title="Connect Wallet" />
    </div>
  );
}

and in parent simply

BaseDialog.tsx

<SettingsDialog />

What you're trying to achieve will be the same, and will fix this unintuitive, in this scenario, error.

In my examples, I've assumed that BaseDialog has a required prop with a name title.

Upvotes: 0

MocXi
MocXi

Reputation: 466

Just want to add a case to this question. I walked around this issue by swapping the order of import, for example in my mixed of imports before:

import { Label } from 'components/forms/label';
import Loader from 'components/loader/loader';
...
import Select from 'components/select/select'; // <----- the error happen

After the change:

import Select from 'components/select/select'; // <----- Fixed
import { Label } from 'components/forms/label';
import Loader from 'components/loader/loader';
...

Upvotes: 2

Steven Abaco
Steven Abaco

Reputation: 41

I was getting this error also. The error was being caused by trying to export a component like this...

export default Component();

Instead of like this...

export default Component;

My understanding is that by adding the "()" at the end of the component, I was actually calling the function instead of just referencing it.

I did not see this in the answers above, but may have missed it. I hope it helps someone and saves some time. It took me a long time to pinpoint the source of this error!

Upvotes: 3

Sigex
Sigex

Reputation: 2949

I was getting this issue too. My imports look fine, I could copy the contents of my copy and paste it where it was being used and that worked. But it was the reference to the component that was going wrong.

For me I just had to shut down expo and restart it.

Upvotes: 2

jasonleonhard
jasonleonhard

Reputation: 13877

Given your error of:

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

You have 2 options:

  1. Your export file can have the word default as in
export default class someNameHere

Then your import will need to avoid using {} around it. As in

import somethingHere from someWhereHere
  1. Avoid using the default word. Then your export looks like
export class someNameHere

Then your import must use the {}. Like

import {somethingHere} from someWhereHere

Upvotes: 31

RonH
RonH

Reputation: 514

In my case I had written const Tab = createBottomTabNavigator instead of const Tab = createBottomTabNavigator()

Upvotes: 0

Sudheer Kumar Palchuri
Sudheer Kumar Palchuri

Reputation: 2954

By mistake i tried to import Container and Content from react-native instead of native-base.

Error because of this line:

import { ActivityIndicator, RefreshControl,  StyleSheet, View, Keyboard, Container, Content } from 'react-native';

Below is the code fix:

import { ActivityIndicator, RefreshControl,  StyleSheet, View, Keyboard } from 'react-native';
import { Container, Content} from 'native-base';

Upvotes: 0

Noimang
Noimang

Reputation: 11

exporting at the bottom of the file might solve it.

const IndicatorCloak = (props) => { ... }
export default IndicatorCloak;

Upvotes: 0

Katti
Katti

Reputation: 2121

In my case, one of the exported child module was not returning a proper react component.

const Component = <div> Content </div>;

instead of

const Component = () => <div>Content</div>;

The error shown was for the parent, hence couldn't figure out.

Upvotes: 40

hackemate
hackemate

Reputation: 537

I was the same problem because I did import incorrect library, so i checked the documentation from the library and the route was changed with the new versión, the solution was this:

import {Ionicons} from '@expo/vector-icons';

and I was writing the incorrect way:

import {Ionicons} from 'expo';

Upvotes: 2

Simon
Simon

Reputation: 6452

The problem can also be an alias used for a default export.

Change

import { Button as ButtonTest } from "../theme/components/Button";

to

import { default as ButtonTest } from "../theme/components/Button";

solved the issue for me.

Upvotes: 2

Naxxa Consulting
Naxxa Consulting

Reputation: 51

I got this error in react routing, problem was that I was using

<Route path="/" component={<Home/>} exact />

but it was wrong route requires component as a class/function so I changed it to

<Route path="/" component={Home} exact />

and it worked. (Just avoid the braces around the component)

Upvotes: 5

Eugene Ihnatsyeu
Eugene Ihnatsyeu

Reputation: 1585

I had an issue with React.Fragment, because the version of my react was < 16.2, so I got rid of it.

Upvotes: 1

JohnL
JohnL

Reputation: 14106

In my case (using Webpack) it was the difference between:

import {MyComponent} from '../components/xyz.js';

vs

import MyComponent from '../components/xyz.js';

The second one works while the first is causing the error. Or the opposite.

Upvotes: 1266

Sathesh
Sathesh

Reputation: 496

In my case, it was the meta tags.

I was using

const MetaTags = require('react-meta-tags');

I guess MetaTags is a default export, So changing to this solved it for me, took hours to figure out which one was causing it.

const { MetaTags } = require('react-meta-tags');

Upvotes: 0

Related Questions