如何使用 import () 在 React 中动态加载组件?



我尝试使用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.dirimport 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)

相关内容

  • 没有找到相关文章

最新更新