尝试在另一个目录中导入组件时,动态导入反应不起作用 [英] Dynamic import in react not working when trying to import a component in another directory

查看:97
本文介绍了尝试在另一个目录中导入组件时,动态导入反应不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我一直在尝试动态导入来为使用 CRA (create-react-app) 创建的应用程序渲染我的组件,虽然它在某些情况下运行良好,但对于某些情况,它返回一个无法加载模块的错误,例如我在我的 index.js 中动态加载了一个组件(放置在 src 下的目录中),它工作正常,但是当我尝试使用动态导入方法在其中呈现子组件或嵌套组件时,它会出错无法加载模块.请注意,仅当嵌套组件放置在原始父组件的目录之外时才会发生此错误,这里是代码.

我的 index.js 放在 src 下.

 import React, { Component } from 'react';从 'react-dom' 导入 ReactDOM;导入'./index.css';类动态扩展组件{构造函数(道具){超级(道具);this.state = { 模块:null };}componentDidMount() {console.log('in comp mount')//警报(在补偿安装中")const { 路径 } = this.props;导入(`${path}`).then(module => this.setState({ module: module.default }))}使成为() {console.log('在渲染')//警报(渲染中")const { 模块:组件 } = this.state;//分配给新的变量名@see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment返回(<div>{组件&&<组件路径='../FooterComp/Footer'/>}

)}}ReactDOM.render(<Dynamic path='./Components/FirstComponent'/>, document.getElementById('root'));

FirstComponent.js 放在 src 下的 Components 目录中.

import React, { Component } from 'react';从'../logo.svg'导入标志;导入'../FirstApp.css';类 App 扩展组件 {构造函数(道具){超级(道具);this.state = { 模块:null };}componentDidMount() {console.log('in comp mount')//警报(在补偿安装中")const { 路径 } = this.props;警报(路径)导入(`${path}`).then(module => this.setState({ module: module.default }))}使成为() {const { 模块:组件 } = this.state;返回 (<div className="应用程序"><header className="App-header"><img src={logo} className="App-logo" alt="logo"/><p>编辑 <code>src/App.js</code>并保存以重新加载.</p>

);}}导出默认应用程序;

Footer.js 放置在 src 下的 FooterComp 目录中.

import React, { Component } from 'react';导入'../App.css';类页脚扩展组件{组件DidMount(){console.log('在页脚的 componentDidMount')}使成为() {console.log('在页脚的渲染中')返回 (<div className="应用程序"><h1>由我编辑</h1>

);}}导出默认页脚;

为什么当我从我的 index.js 引用我的第一个组件时这有效,但在尝试导入我的第一个组件时不适用于页脚组件?

错误消息:错误:找不到模块../FooterComp/Footer"

还要注意,如果我将页脚组件放在与 Firstcomponent 相同的目录中并调整路径,它就可以正常工作

解决方案

使用带有可变部件的动态导入时存在限制.

Webpack 文档

<块引用>

不可能使用完全动态的导入语句,例如 import(foo).因为 foo 可能是系统或项目中任何文件的任何路径.

<块引用>

import() 必须至少包含一些关于模块所在位置的信息.捆绑可以限于特定目录或文件集,以便在使用动态表达式时 - 包括可能在 import() 调用中请求的每个模块.例如, import(./locale/${language}.json) 将导致 ./locale 目录中的每个 .json 文件被捆绑到新块中.在运行时,当变量语言被计算出来时,任何像 english.json 或 German.json 的文件都可以使用.

在您的情况下,在 FirstComponent 组件中动态导入的构建期间,捆绑仅限于 FirstComponent 组件所在的目录,即 Components目录.

意思是,webpack会找到Components目录下的所有文件,然后创建 给他们.然后在运行时调用动态导入时,webpack 会为传入的值对应的块提供服务.

因为你通过了 path='../FooterComp/Footer' 没有对应的块,所以 webpack 会抛出错误.

Dynamic 组件也是如此.如果您尝试为 src 文件夹之外的文件动态导入可变部分,您将得到相同的错误.

所以要解决这个问题,你有几个选择

  1. 将两个文件放在同一个文件夹中

'src/Components/FirstComponent.js''src/组件/Footer.js'

并使用

//在 FirstComponent.js 中componentDidMount() {const { 路径 } = this.props;导入(`${path}`).then(module => this.setState({ module: module.default }))}{组件&&<Component path='./Footer'/>}//Index.js

  1. 尽可能具体

//在 FirstComponent.js 中componentDidMount() {const { 路径 } = this.props;导入(`../FooterComp/${path}`).then(module => this.setState({ module: module.default }))}

并使用

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

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

解决方案

There’s limitation when using dynamic imports with variable parts.

Webpack Docs

It is not possible to use a fully dynamic import statement, such as import(foo). Because foo could potentially be any path to any file in your system or project.

The import() must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an import() call is included.For example, import(./locale/${language}.json) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.

In your case, during build time for dynamic import in FirstComponent component, bundling was limited to directory where the FirstComponent component was i.e. Components directory.

What it means is that, webpack will find all the files that are in the Components directory and then create chunks for them. Then at runtime when dynamic import is called, webpack will serve the chunk that corresponds to the value passed in.

Since you passed path= '../FooterComp/Footer' has no corresponding chunk so webpack will throw the error.

This is also same for Dynamic component. If you try to dynamically import 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.js'

'src/Components/Footer.js'

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

  1. 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

这篇关于尝试在另一个目录中导入组件时,动态导入反应不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆