Dynamic import in react not working when trying to import a component in another directory

霸气de小男生 提交于 2020-08-23 03:36:37

问题


Hello everyone I have been trying dynamic imports in react for rendering my components for an app created with CRA (create-react-app) and while it works perfectly for some cases but for some it returns a cannot load module error for instance I loaded a component(placed in a directory under src) dynamically in my index.js which works fine but when I try to render a child or nested component inside that also with a dynamic import approach it gives error cannot load module. Note this error occurs only if the nested component is placed outside the directory of the original parent component enough talk here is the code.

My index.js placed under src.

    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'));

FirstComponent.js placed in Components directory under src.

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;

Footer.js placed in FooterComp directory under src.

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;

Why does this work when I refer my firstcomponent from my index.js but doesnt work for footer component when trying to import in my firstcomponent?

Errormessage: Error: Cannot find module '../FooterComp/Footer'

Also note that if i place Footer component in the same directory as Firstcomponent and adjust the path it works fine


回答1:


There’s limitation when using dynamic imports with "variable parts" like import(`${path}`).

During Webpack bundle creation

In your case when import(`${path}`) in Dynamic component was called, webpack created a bundle. That bundle was for FirstComponent component. Inside that bundle webpack provided list of components which you could dynamically import with "variable parts" in FirstComponent component. It only contains files that are inside the same folder where FirstComponent component was. This is because you used import(`${path}`) in FirstComponent.

This all happens because webpack at compile does not know what will be the exact import path at runtime as you are using dynamic imports with "variable parts".

During React app request

When import(`${path}`) was executed in Dynamic Component. Bundle for FirstComponent was requested. As soon as the bundle was received and it executed its code and the path you provided as props to FirstComponent component was not in the list of components which you could dynamically import with "variable parts".

This is also same for Dynamic component if you try to dynamically import files with "variable parts" for the files that are outside src folder you will get same error.

So to solve this you have couple of options

1) place both files in same folder

i.e

'src/Components/FirstComponent'

'src/Components/Footer'

And use

// In FirstComponent.js
   componentDidMount() {
      const { path } = this.props;
      import(`${path}`)
      .then(module => this.setState({ module: module.default }))   
   }


{Component && <Component path='./Footer' />} // Index.js

2) be more specific as possible

i.e

// In FirstComponent.js
 componentDidMount() {
      const { path } = this.props;
      import(`../FooterComp/${path}`)
      .then(module => this.setState({ module: module.default }))   
 }

And use

{Component && <Component path='Footer' />} //  In index.js



回答2:


If FooterComp is under src, the path should be './FooterComp/Footer' not '../FooterComp/Footer'


Edit

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>
    );
  }


来源:https://stackoverflow.com/questions/54254553/dynamic-import-in-react-not-working-when-trying-to-import-a-component-in-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!