I tried to use import()
instead of React.lazy
to dynamically load components, but it didn't work.
App.js
import React, { useState } from 'react';
function App() {
const [Com, setCom] = useState(null);
const handleClick = () => {
import("./A.js").then(c => {
//console.log(c.default)
setCom(c.default)
})
}
return (
<div>
<button onClick={handleClick}>Load</button>
{ Com ? <Com /> : null }
</div>
);
}
export default App;
A.js
import React from "react";
export default function A () {
return (<div>A</div>)
}
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
In fact, I printed out c.default
. It's really a function.
c.default
ƒ A() {
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
__source: {
fileName: _jsxFileName,
lineNumber: 4
},
__self: this
}, "A");
}
Actually, it's not related to the dynamic import
but the useState
implementation. For example:
import Comp from "./A";
function App() {
const [Com, setCom] = useState(Comp);
return (
<div>
<Com />
</div>
);
}
Will throw the same error. That's because when you call useState(Comp)
, Comp
"function" (which is the Component) been execute (you can test it by removing any <Com />
from the code and adding console.log
inside A
. The console.log
still appears).
As a result Com
is no longer a Component but a JSX element. When you try to render JSX element in a function way (meaning wrapping it with <
and />
, this error thrown.
The solution is either to set Com
as a component (() => Com
) or to render it as a JSX child ({Com}
)
import React, { useState } from "react";
function App() {
const [Com, setCom] = useState(null);
const handleClick = () => {
import("./A.js").then(c => {
//console.log(c.default)
setCom(c.default);
});
};
return (
<div>
<button onClick={handleClick}>Load</button>
{/* <Comp /> */}
{Com}
</div>
);
}
export default App;
https://codesandbox.io/s/answer-for-httpsstackoverflowcomq62125854863110-jj2wu
BTW, you can see the difference by console.dir
the original outcome of import Comp from "./A";
and the outcome of useState(Comp)
import Comp from "./A";
function App() {
const [Com, setCom] = useState(Comp);
// console.log(1, Com, 2, Comp);
console.dir(Com) // Object
console.dir(Comp) // ƒ A()
//...
}