简体   繁体   中英

How to dynamically import a component in React?

I am trying to optimize a component of mine with dynamic rendering, but I'm facing some issues, so this is my current situation:

I have an Alert component that renders an alert message, along with an icon.

I have a Icons module, which is a library of icons

I am currently rendering the icon as follows (this is not actual code, it's just to give the idea):

import * as icons from '../icons';
import DefaultIcon from '../icons';

function Alert(iconName='defaultIcon', message) {  

  function getIcon(iconName) {
    if (iconName === 'defaultIcon') {
      return DefaultIcon()
    }
    return icons[iconName]
  }

  return (
    <div>
      <span>{getIcon(iconName)}</span>
      <span>{message}</span>
    </div>

  )
}

So, suppose Alert gets called without iconName most of the times, so the components doesn't need to import all of the icons at all.

I would like to avoid including all of the icons in the Alert component by default, but only doing so if iconName is specified

Is it even possible to do so?

I don't think it's possible this way.

Maybe create a component for the Icon that imports the icon libary. In the Alert component you could implement the Icon component as a child:

<Alert message="Alert!">
  <Icon iconName="defaultIcon" />
</Alert>

You should import icons dynamically with type or name etc. something like below.

import React from 'react';

export default function Icon({ type, ...props }) {
  const Icon = require(`./icons/${type}`).default;

  return <Icon {...props} />
}

import Icon from './Icon';

<Icon type="addIcon" />

Ok, looks like I managed, and that's how I did it:

import DefaultIcon from '../icons';

function Alert(message, iconName="") {
  const [icon, useIcon] = useState();

  //componentDidMount
  const useEffect(() => {
    //if an icon name is specified, import the icons
    if (iconName) {
      import("./icons").then(icons => setIcon(icons[iconName]))
    } else {
      setIcon(DefaultIcon)
    }
  }
  ,[])
  
  return (
    <span>{icon}</span>
    <span>{message}</span>
  )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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