简体   繁体   English

React:动态导入jsx

[英]React: dynamic import jsx

This question related to dynamically importing JSX files into React. 此问题与将JSX文件动态导入React有关。

Basically we have one main component that dynamically renders other components based on a structure stored in a database. 基本上我们有一个主要组件,它根据存储在数据库中的结构动态呈现其他组件。 The dynamic components are stored in a subdirectory "./Components". 动态组件存储在子目录“./Components”中。 We statically define the this as: 我们将此静态定义为:

import CompA  from './Components/CompA';
import CompB  from './Components/CompB';

var components = {
 'CompA': CompA,
 'CompB': CompB
}

and we render them using: 我们使用以下方式渲染它们

var type = 'CompA' 
var Component = components[type];
...
<Component />

While this works fine, it is a bit too static for us. 虽然这很好用但对我们来说有点太静态了。 We have 100+ components (CompA/CompBs) and statically define them does not work. 我们有100多个组件(CompA / CompBs)并静态定义它们不起作用。

Is it possible to import all JSX files in "./Compontents" and populate the components-array? 是否可以在“./Compontents”中导入所有JSX文件并填充components-array?

And, what would be really (really) nice would be if we could send the "./Components" path as a prop to the main components. 而且,如果我们可以将“./Components”路径作为主要组件的支柱发送,那真正(真正)好的将是什么。 And the main component would use this path to import the .jsx files. 主要组件将使用此路径导入.jsx文件。 Like this: 像这样:

<MainComponent ComponentPath="./SystemComponents">

Would use "./SystemComponents" as path for .JSX files and: 将使用“./SystemComponents”作为.JSX文件的路径,并且:

<MainComponent ComponentPath="./UserComponents">

Would use "./UserComponents" as import path. 将使用“./UserComponents”作为导入路径。

What about having a components/index.js with contents: 如果有一个包含内容的components / index.js呢:

export CompA from "./comp_a";
export CompB from "./comp_b";

Then you do: 然后你做:

import * as Components from "./components"

then you would use as: 然后你会用作:

<Components.CompA />
<Components.CompB />
...

Hope this helps. 希望这可以帮助。

I doubt you can load anything when sending path through component props, loading of the file should then happen inside the React component lifecycle methods which is not something I would recommend. 我怀疑你在通过组件道具发送路径时可以加载任何东西,然后应该在React组件生命周期方法内部加载文件,这不是我建议的。

To complement @gor181's answer, I can add that export s must be this way: 为了补充@ gor181的答案,我可以补充一点, export必须是这样的:

export { default as CompA } from "./comp_a"; export { default as CompB } from "./comp_b";

Hope this might be helpful. 希望这可能会有所帮助。

As of React 16.6.0 , we can lazy-load components and invoke them on-demand. React 16.6.0开始 ,我们可以延迟加载组件并按需调用它们。

The Routing 路由

// We pass the name of the component to load as a param
<Switch>
  …
  <Route path="/somewhere/:componentName" component={MyDynamicComponent} />
</Switch>

views/index.js 意见/ index.js

import { lazy } from 'react';

const SomeView = lazy(() => import('./SomeView'));
const SomeOtherView = lazy(() => import('./SomeOtherView'));

export { SomeView, SomeOtherView };

MyDynamicComponent.js MyDynamicComponent.js

import React, { Suspense, Component } from 'react';
import { PropTypes } from 'prop-types';
import shortid from 'shortid'; // installed separately via NPM
import * as Views from './views';

class MyDynamicComponent extends Component {
  render() {
    const {
      match: {
        params: { componentName },
      },
    } = this.props;

    const Empty = () => <div>This component does not exist.</div>;
    const dynamicComponent = (() => {
      const MyComponent = Views[`${componentName}View`]
        ? Views[`${componentName}View`]
        : Empty;
      return <MyComponent key={shortid.generate()} />;
    })();

    return (
      <>
        <Suspense fallback={<div>Loading…</div>}>{dynamicComponent}</Suspense>
      </>
    );
  }
}
MyDynamicComponent.propTypes = {
  match: PropTypes.shape({
    params: PropTypes.shape({
      componentName: PropTypes.string.isRequired,
    }),
  }),
};

export default MyDynamicComponent;

Usage 用法

{items.map(item => (
  <NavLink to={`/somewhere/${item.componentName}`}>
    {item.name}
  </NavLink>
))}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM