我尝试使用import()
而不是React.lazy
来动态加载组件,但它不起作用。
应用.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;
答.js
import React from "react";
export default function A () {
return (<div>A</div>)
}
错误:元素类型无效:需要字符串(对于内置组件(或类/函数(对于复合组件(,但得到:对象。
事实上,我打印了c.default
.这确实是一个功能。
c.默认
ƒ A() {
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
__source: {
fileName: _jsxFileName,
lineNumber: 4
},
__self: this
}, "A");
}
实际上,它与动态import
无关,而是与useState
实现有关。例如:
import Comp from "./A";
function App() {
const [Com, setCom] = useState(Comp);
return (
<div>
<Com />
</div>
);
}
将抛出相同的错误。这是因为当您调用useState(Comp)
时,Comp
"函数"(即组件(已执行(您可以通过从代码中删除任何<Com />
并在A
中添加console.log
来测试它。console.log
仍然显示(。
因此Com
它不再是一个组件,而是一个JSX元素。当您尝试以函数方式渲染 JSX 元素时(意味着用<
和/>
包装它,会抛出此错误。
解决方案是将Com
设置为组件(() => Com
(或将其呈现为JSX子组件({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
顺便说一句,您可以通过console.dir
import Comp from "./A";
的原始结果和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()
//...
}
如果使用函数调用 setState,它将以前一个值作为参数执行。
const [count,setCount] = useState(0)
setCount(prevCount => prevCount + 1)
在您的情况下,React 不会使用导入的函数更新状态,而是会执行它,结果将被设置为状态。
溶液:
setCom(() => c.default)