Home > Software design >  Is There anyway to Render a component from an object? -React
Is There anyway to Render a component from an object? -React

Time:09-02

ok guys I have a problem.

I need render a list which has a title and a icon . and I Want to render it dynamic with map method.

This is the backend api object(Its more than 2 :D )

// icons are Material UI Icon component
const list = [
{title: 'Vehicle', icon: 'DirectionsCarFilledOutlined'},
{title: 'Electronic', icon: 'PhoneIphoneOutlined'},
]

What I have to do is to render this icon COMPONENT dynamic

something like this

import {
  DirectionsCarFilledOutlined,
  PhoneIphoneOutlined,
} from "@mui/icons-material";


const list = [
{title: 'Vehicle', icon: 'DirectionsCarFilledOutlined'},
{title: 'Electronic', icon: 'PhoneIphoneOutlined'},
]

              {list.map(({ title, icon }) => {
                return (
                  <div>
                    <p>{title}</p>
                    <div>{<icon />}</div> // Problem is here. IDK How to render it 
                  </div>
                );
              })}

I Wrote switch case for this problem but that's bad and if we add new items to api those lists won't have icon.

Is there anyway to render this Icons dynamic ?

CodePudding user response:

You can solve your problem by using React.lazy to LazyLoad icons, given that the icon value corresponds to an exact path from @mui/icons-material.

To do so, first we need to define a lazy function that can return non-default exports, since React.lazy expects to return a default import


// iconName is still undefined, but we'll get to it
const Icon = lazy(() =>
  import("@mui/icons-material").then(module => ({ default: module[iconName] }))
);

Then, we'll write an Item component, which receives iconName as a prop and LazyLoads it, utilizing React.Suspense to allow for the component to be rendered.


import React, {lazy, Suspense} from 'react'

const Item = ({title, iconName}) => {
  const Icon = lazy(() =>
    import("@mui/icons-material").then(module => ({ default: module[iconName] }))
  );

  return (
    <div>
      <p>{title}</p>
      <div>
        <Suspense fallback={<></>}>
          <Icon/>
        </Suspense>
      </div>
    </div>
  )
}

You should then import Item inside your component and return Items from your map.

CodePudding user response:

Hope this could be the solution for you.

You can directly set the icon element imported from @mui/icons-material as the value of the icon of the list item.

import {
  DirectionsCarFilledOutlined,
  PhoneIphoneOutlined,
} from "@mui/icons-material";


const list = [
  {title: 'Vehicle', icon: DirectionsCarFilledOutlined},
  {title: 'Electronic', icon: PhoneIphoneOutlined},
]

... in render part

          {list.map(({ title, icon }) => {
            return (
              <div>
                <p>{title}</p>
                <div><icon /></div> // Problem is here. IDK How to render it 
              </div>
            );
          })}
  • Related