I am using React createElement in 5 components of my application. This was working fine when running react and react-dom version 17.0.2. I recently upgraded to version 18.2.0 and now I am getting the error message:
Warning: React.createElement: 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 is defined in, or you might have mixed up default and named imports.
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 is defined in, or you might have mixed up default and named imports.
at renderElement (C:\Users\jterr\Documents\NodeProjects\TeachLearnPlay\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:6047:9)
at renderNodeDestructiveImpl (C:\Users\jterr\Documents\NodeProjects\TeachLearnPlay\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:6108:11)
There is more to the error message but I have omitted for brevity.
Note that the error message does not indicate any of my components to be an issue. It does reference Node modules.
This was a fresh install. I had removed the node_modules folder and the package-lock.json file prior to the npm install command.
I have seen all of the similar questions with this message and have checked and double checked that I am "exporting default" each of the components. I have tried placing the "export default" on the initial function definition and have also put it at the bottom of the component as it sits now.
I am using server side rendering.
Below is an example where I am using the createElement. Below that is the component that it is trying to create. Note that I have commented out other components that would normally be created so that I can focus on solving this without having to change multiple components.
//import React from "react";
//import DisplayAssociation from "./displayAssociation";
import DisplayDefinition from "./displayDefinition";
//import DisplayQuestionMultiChoice from "./displayQuestionMultiChoice";
//import DisplaySegment from "./displaySegment";
//import DisplayStatement from "./displayQuestionMultiChoice";
const Components = {
//Association: DisplayAssociation,
Definition: DisplayDefinition,
/*
QuestionMultiChoice: DisplayQuestionMultiChoice,
//Quote: DisplayQuote,
//Prefix: DisplayPrefix,
Segment: DisplaySegment,
Statement: DisplayStatement,
//Suffix: DisplaySuffix,
*/
};
export const DisplayConstructSwitch = ( block,
finalDisplayConstructs,
setFinalDisplayConstructs,
displayFramework,
setDisplayFramework,
okToChange,
completed,
numberCorrect,
setNumberCorrect,
numberWrong,
setNumberWrong,
totalAttempts,
setTotalAttempts, ) => {
// component does exist
console.log("DisplayConstructSwitch - start block = ", block );
console.log("DisplayConstructSwitch - start block.subType = ", block.subType );
console.log("DisplayConstructSwitch - start typeof Components[block.subType] = ", typeof Components[block.subType] );
if (typeof Components[block.subType] !== "undefined") {
return React.createElement(Components[block.subType], {
key: block.constructId,
finalDisplayConstruct: block,
finalDisplayConstructs: finalDisplayConstructs,
setFinalDisplayConstructs: setFinalDisplayConstructs,
displayFramework: displayFramework,
setDisplayFramework: setDisplayFramework,
okToChange: okToChange,
completed: completed,
numberCorrect: numberCorrect,
setNumberCorrect: setNumberCorrect,
numberWrong: numberWrong,
setNumberWrong: setNumberWrong,
totalAttempts:totalAttempts,
setTotalAttempts: setTotalAttempts,
});
}
// component doesn't exist yet
return React.createElement(
() => <div>The component {block.constructResponseFormat} has not been created yet.</div>,
{ key: block.constructId }
);
}
Here is the DisplayDefinition Component that should be created.
import React, { useState, useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
const useStyles = makeStyles((theme) => ({
paper: {
padding: theme.spacing(1),
display: "flex",
overflow: "auto",
flexDirection: "column",
},
}));
function DisplayDefinition(props) {
const {displayConstruct} = props;
const classes = useStyles();
const wordToDefine = displayConstruct.constructDetail.wordToDefine;
const wordDefinitions = displayConstruct.constructDetail.wordDefinitions;
console.log("DisplayDefinition - wordToDefine = ", wordToDefine );
console.log("DisplayDefinition - wordDefinitions = ", wordDefinitions );
useEffect(() => {
console.log("DisplayDefinition - in useEffect - wordToDefine = ", wordToDefine );
}, [wordToDefine]);
return (
<>
<Paper className={classes.paper} elevation={3}>
<label>
Word to Define: {wordToDefine}
</label>
<label>
Definition: {wordDefinitions[0]}
</label>
</Paper>
</>
)
}
export default DisplayDefinition;
The only code changes in these components between the versions was to comment out extra components while I trouble shoot.
Can anyone see any issue with what I have done that would have allowed version 17 to work but not version 18?
Can it be that this code is fine but there is some other change that I need to make and it is manifesting itself as a false createElement issue? If so, what might that be?
Related
Many times I've seen this error, and honestly I never know how to fix it, or how i fixed it in the past ...
Uncaught 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.
Here's my component implementation, I'm trying to understand what's wrong.
import React from 'react';
import { SvgFromUri } from 'react-native-svg';
import { Image } from 'react-native';
import { AppColors } from '../constants';
const imgSize = 55;
const CompanyIcon = ({ url }) => {
return (
<>
{
url && !url.includes('favicon')
? <SvgFromUri uri={url} width={imgSize} height={imgSize} onError={console.error} />
: <Image source={require('../assets/app_icon48.png')} style={
{
borderWidth: 1,
borderColor: AppColors.LIGHT_BLUE,
borderRadius: 4,
width: imgSize,
height: imgSize
}
} />
}
</>
);
}
export default CompanyIcon;
Thanks so much for any help community
The options I found research about it said something about exporting the component as default, so I did, but no success :(
Update:
Looks like it's a bug within the svg component :|
https://github.com/software-mansion/react-native-svg/issues/1742
check your exports, if you have a default export you should import like this :
import FunctionName from '../location'; // without {}
or maybe you
forgot to export your component from the file it's defined in, or you might have mixed up default and named imports
I am making a calendar with React but this problem show when I try to run it:
yarn start "Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. 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 Calendar."
my Calendar.jsx code:
import React, { useRef,useState } from "react";
import FullCalendar from '#fullcalendar/react'
import dayGridPlugin from '#fullcalendar/daygrid'
import AddEventModal from "./AddEventModal";
function Calendar () {
const[modalOpen, setModalOpen] = useState(false);
const calendarRef =useRef(null);
const onEventAdded = event =>{
let calendarApi = calendarRef.current.getApi();
calendarApi.addEvent(event);
}
return(
<section>
<button>Add Event to the Calendar</button>
<FullCalendar
ref={calendarRef}
plugins={[ dayGridPlugin ]}
initialView="dayGridMonth"
/>
<AddEventModal isOpen={modalOpen}
onClose={() => setModalOpen(false)}
onEventAdded={event => onEventAdded(event)}/>
</section>
)
}
export default Calendar
Ran into the same issue (but wasn't using a modal). Turns out the import URL of the component was wrong. That is the error message React v17 gives you when the file's URL is wrong apparently. Might wanna check your import?
I'm trying to create a new Gatsby plugin. I started with developing it as a local plugin. In this plugin I want to provide a wrapPageElement for server side rendering and during runtime, so I've create the following configuration files:
gatsby-ssr.js:
export { wrapPageElement } from "./src/wrapPageElement";
gatsby-browser.js:
export { wrapPageElement } from "./src/wrapPageElement";
src/wrapPageElement.tsx:
import React from "react";
import { GatsbyBrowser, GatsbySSR } from "gatsby";
type WrapPageElement =
| GatsbyBrowser["wrapPageElement"]
| GatsbySSR["wrapPageElement"];
export const wrapPageElement: WrapPageElement = ({ element, props }: any) => {
return <div {...props}>{element}</div>;
};
Now when I run my Gatsby project I get the following runtime error:
One unhandled runtime error found in your files. See the list below to fix it:
Unknown Runtime Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `PageRenderer`.
:
No codeFrame could be generated
When I don't try to render {element} within the wrapPageElement, for example a simple string, the wrapPageElement is successfully rendered. The problem seems to be related to element. Does somebody have an idea what is wrong here?
I'm on Gatsby version 3.14.0.
It seems to be unresolved (yet) according to this GitHub thread, where apparently types are not properly exported by Gatsby.
As a hacky workaround you can try:
type Fn = (...args: Parameters<WrapPageElement>) => ReturnType<WrapPageElement>
export const wrapPageElement: Fn = ({ element, props }: any) => {
return <div {...props}>{element}</div>;
};
Note: modified from the source in the GitHub's thread
The problem was, that my page I tried to render didn't have a default export.
Instead of ..
import React from "react";
export default function IndexPage() {
return <div>
Index
</div>
}
.. I defined ..
import React from "react";
export function IndexPage() {
return <div>
Index
</div>
}
.. what caused the error.
in our project we have around 10 animations that are using react-lottie library and are loaded with loadable-component library. Some of these animations are crashing on Gatsby development environment. I have managed to narrow down which ones are failing on my end and there were 2.
The component is built like this:
#LottieComponent.tsx
import React, { CSSProperties } from 'react';
import Lottie from 'lottie-react';
import json from './lottieAnimation.json';
interface Props {
styles?: CSSProperties;
}
export default ({ styles }: Props) => (
<Lottie style={styles} animationData={json} />
);
Then we use code splitting:
#index.tsx
import loadable from '#loadable/component';
const ExchangeInfographic = loadable(
() => import('./animationComponents/ExchangeGraphic')
);
export {
ExchangeInfographic
};
Then we import the component into the module like this:
import { ExchangeInfographic } from '../../components/Infographic';
const ExampleComponent = () => {
const [animationWasRendered, setAnimationWasRendered] = useState(false);
return (
<ReactVisibilitySensor
onChange={(isVisible) => {
isVisible && setAnimationWasRendered(true);
}}
partialVisibility
>
<SectionCustomComponent>
<Container>
<Col>
{animationWasRendered ? <ExchangeInfographic /> : <></>}
</Col>
</Row>
</Container>
</Section>
</ReactVisibilitySensor>
);
};
export default ExampleComponent;
The error that I get in the console is:
react-dom.development.js:23966 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `InnerLoadable`.
I have check the possible reasons for this error message and found this thread:
https://github.com/facebook/react/issues/13445
and
Code splitting/react-loadable issue
but it doesn't look as if the dynamic import would fail. The confusing part is that, why would it only crash on some animations and the other work fine every time. O.o
Would you have an idea what am I missing?
Thanks for any suggestions!
I'm not sure if it will fix the issue because I don't know all the specs nor your use-case, but this export seems odd to me:
#index.tsx
import loadable from '#loadable/component';
const ExchangeInfographic = loadable(
() => import('./animationComponents/ExchangeGraphic')
);
export {
ExchangeInfographic
};
Have you tried something like:
#index.tsx
import loadable from '#loadable/component';
const ExchangeInfographic = loadable(
() => import('./animationComponents/ExchangeGraphic')
);
export ExchangeInfographic
So after few months I decided to give it another try at this weird bug.
Explanation of the issue:
ExchangeInfographic react component had a file name like this ExchangeInfographic.tsx
The json file containing json for the lottie animation had a file name like this exchangeInfographic.json
For some reason when the name of the json file and react component file was the same (except for capital letter for react component) after importing the component like this
import {ExchangeInfographic} from 'path to the file;'
It would return an object instead of function.
To fix it, I just changed the name of the file where json was to for example exchange.json
It's a kind of magic. It's a kind of maaagiiic...
I searched but can't seem to figure out how to change the default loading spinner that is generated with Ant Design Pro V4. I used the generator and ran npm create umi myApp. There is a default four circle spinner that I would like to replace with a customized spinner.
The default loader is located here:
#/myApp/config/config.ts
...
dynamicImport: {
loading: '#/components/PageLoading/index',
},
...
When I modified the PageLoading/index.tsx page based on Ant Design's customer spinner documentation. I kept getting this error.
Error: Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: object.
Check the render method of `LoadableComponent`.
original PageLoading/index.tsx
import { PageLoading } from '#ant-design/pro-layout';
// loading components from code split
// https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
export default PageLoading;
modified PageLoading/index.tsx
import { Spin } from 'antd';
import { LoadingOutlined } from '#ant-design/icons';
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
const CustomSpinner = <Spin indicator={antIcon} />
export default CustomSpinner;
What do I need to do to make it a LoadableComponent? Thanks!
Return value should be a component. Either function or class component.
This would work:
import react from 'react';
import { Spin } from 'antd';
import { LoadingOutlined } from '#ant-design/icons';
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
// Return value should be component
const CustomSpinner = () => <Spin indicator={antIcon} />
export default CustomSpinner;
A new way to doing this. You can define default spin element globally.
//top of app.tsx
import { Spin } from 'antd';
Spin.setDefaultIndicator(<div>Loading</div>);
ant design pro referance
https://ant.design/components/spin/#Static-Method