尝试在另一个目录中导入组件时,React中的动态导入不起作用

时间:2019-01-18 13:00:38

标签: reactjs dynamic-import

大家好,我一直在尝试动态导入,以为使用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放在同一目录中并调整路径,则效果很好

2 个答案:

答案 0 :(得分:3)

将动态导入与import(`${path}`)之类的“可变部分”一起使用时会受到限制。

在创建Webpack捆绑包期间

在您调用import(`${path}`)组件中的Dynamic的情况下,webpack创建了一个包。该捆绑包用于FirstComponent组件。在该捆绑包中,webpack提供了可以通过FirstComponent组件中的“可变部分”动态导入的组件列表。它仅包含与FirstComponent组件所在的文件夹相同的文件。这是因为您在import(`${path}`)中使用了FirstComponent

之所以会发生这种情况,是因为在将动态导入与“可变部分”一起使用时,编译时的webpack不知道运行时的确切导入路径。

在React应用程序请求期间

import(`${path}`)组件中执行Dynamic时。已请求捆绑FirstComponent。收到捆绑包并执行其代码后,您以pathprops组件的形式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>
    );
  }