大家好,我一直在尝试动态导入,以为使用CRA(create-react-app)创建的应用程序呈现组件提供响应,尽管它在某些情况下可以正常工作,但在某些情况下会返回无法加载的模块错误我在submodule
中动态加载了一个组件(放置在src下的目录中),效果很好,但是当我尝试使用动态导入方法在其中渲染子组件或嵌套组件时,它给出了错误,无法加载模块。请注意,仅当嵌套组件放置在原始父组件目录的外部时,才会发生此错误。
我的index.js放在src下。
index.js
FirstComponent.js放在src下的Components目录中。
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class Dynamic extends Component {
constructor(props) {
super(props);
this.state = { module: null };
}
componentDidMount() {
console.log('in comp mount')
//alert("in comp mount")
const { path } = this.props;
import(`${path}`)
.then(module => this.setState({ module: module.default }))
}
render() {
console.log('in render')
// alert("in render")
const { module: Component } = this.state; // Assigning to new variable names @see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
return(
<div>
{Component && <Component path= '../FooterComp/Footer' />}
</div>
)
}
}
ReactDOM.render(<Dynamic path='./Components/FirstComponent' />, document.getElementById('root'));
Footer.js放在src下的FooterComp目录中。
import React, { Component } from 'react';
import logo from '../logo.svg';
import '../FirstApp.css';
class App extends Component {
constructor(props) {
super(props);
this.state = { module: null };
}
componentDidMount() {
console.log('in comp mount')
//alert("in comp mount")
const { path } = this.props;
alert(path)
import(`${path}`)
.then(module => this.setState({ module: module.default }))
}
render() {
const { module: Component } = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
{Component && <Component />}
</div>
);
}
}
export default App;
为什么当我从import React, { Component } from 'react';
import '../App.css';
class Footer extends Component {
componentDidMount()
{
console.log('in componentDidMount of Footer')
}
render() {
console.log('in render of Footer')
return (
<div className="App">
<h1>Edited by Me</h1>
</div>
);
}
}
export default Footer;
引用我的firstcomponent时,此方法起作用,而在尝试导入firstcomponent时,不适用于页脚组件吗?
错误消息:index.js
还请注意,如果将Footer组件与Firstcomponent放在同一目录中并调整路径,则效果很好
答案 0 :(得分:3)
将动态导入与import(`${path}`)
之类的“可变部分”一起使用时会受到限制。
在创建Webpack捆绑包期间
在您调用import(`${path}`)
组件中的Dynamic
的情况下,webpack创建了一个包。该捆绑包用于FirstComponent
组件。在该捆绑包中,webpack提供了可以通过FirstComponent
组件中的“可变部分”动态导入的组件列表。它仅包含与FirstComponent
组件所在的文件夹相同的文件。这是因为您在import(`${path}`)
中使用了FirstComponent
。
之所以会发生这种情况,是因为在将动态导入与“可变部分”一起使用时,编译时的webpack不知道运行时的确切导入路径。
在React应用程序请求期间
在import(`${path}`)
组件中执行Dynamic
时。已请求捆绑FirstComponent
。收到捆绑包并执行其代码后,您以path
到props
组件的形式FirstComponent
不在组件列表中,可以通过“可变零件”动态导入“。
对于Dynamic
组件,这也是相同的,如果您尝试动态导入src
文件夹之外的文件中带有“可变部分”的文件,则会得到相同的错误。
因此,要解决此问题,您有几个选择
1)将两个文件都放在同一文件夹中
即
'src/Components/FirstComponent'
'src/Components/Footer'
并使用
// In FirstComponent.js
componentDidMount() {
const { path } = this.props;
import(`${path}`)
.then(module => this.setState({ module: module.default }))
}
{Component && <Component path='./Footer' />} // Index.js
2)尽可能具体
即
// In FirstComponent.js
componentDidMount() {
const { path } = this.props;
import(`../FooterComp/${path}`)
.then(module => this.setState({ module: module.default }))
}
并使用
{Component && <Component path='Footer' />} // In index.js
答案 1 :(得分:0)
如果FooterComp在src下,则路径应为'./FooterComp/Footer'
而不是'../FooterComp/Footer'
修改
Index.js
render() {
console.log('in render')
// alert("in render")
const { module: Component } = this.state;
return(
<div>
{Component && <Component path='./Components/FirstComponent' />}
</div>
)
}
}
ReactDOM.render(<Dynamic />, document.getElementById('root'));
FirstComponent.js
render() {
const { module: Component } = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
{Component && <Component path= '../FooterComp/Footer' />}
</div>
);
}