2

I am using icon component with '@fluentui/react-northstar' library as as below

import { QnaIcon } from '@fluentui/react-northstar'
const Example1 = () => (
  <>
    <QnaIcon size="large" />
  </>
) 

Now I have to dynamically load the icon component when icon name is come from prop something like this

import React from 'react'
import { Button, TeamCreateIcon   } from '@fluentui/react-northstar' 

const Example2 = ({iconName}) => {
 
const MyIcon = <iconName /> ; //here I need to convert string to component 

return (
  <div >
     <Button icon={<TeamCreateIcon />} title="Create" />
     // Here I need set it
     <Button icon={<MyIcon />} title="Create" />    
  </div>
)} 
<Example2 iconName='QnaIcon' />  

code https://codesandbox.io

DevÁsith
  • 1,072
  • 12
  • 38
  • 1
    Can you pass the icon itself in props instead of just the icon name? – squillman Mar 04 '21 at 13:20
  • @squillman I have to pass icon name from a json & it is configurable – DevÁsith Mar 04 '21 at 13:30
  • I was just thinking that the other component could determine the icon since it's already determining which one you need. Keep the logic in one place. You can still parse the JSON in the other component to get the icon and pass it to this component. – squillman Mar 04 '21 at 13:37

2 Answers2

2

I am Brazilian and therefore I speak Portuguese, but I will use the translator to try to help you.

What you can do is the following:

import React from 'react'
import { Button, TeamCreateIcon   } from '@fluentui/react-northstar' 

const Example2 = ({iconName}) => {

const ICONS = {
  iconLike: <YourLikeIcon/>,
  iconMenu: <YourMenuIcon/>,
}

return (
  <div >
     <Button icon={<TeamCreateIcon />} title="Create" />
     // Here I need set it
     <Button icon={ICONS[iconName]} title="Create" />    
  </div>
)} 

But you must be careful with iconName, because if it is not correct it can give an error. To prevent you can do some tests beforehand.

Uéslei Suptitz
  • 325
  • 1
  • 7
  • This is great. however in your scenario i have to add all icons . i created sandbox demo https://codesandbox.io/s/fluent-ui-example-forked-2xtbt?file=/example.js:277-286 – DevÁsith Mar 04 '21 at 13:47
1

I would rather do it in a different way. I would pass the component itself as props to Example2

<Example2>
  <Icon/>
</Example2>

In the actual component, I would use props.children, which contains the child component that we mentioned as above

import React from 'react'

const Example2 = () => {
 

return (
  <div >
     <Button icon={props.children} title="Create" />
     <Button icon={<MyIcon />} title="Create" />    
  </div>
)} 

EDIT

Including the codesandbox link as well

https://codesandbox.io/s/fluent-ui-example-forked-p5lkk?file=/example.js

Near
  • 379
  • 1
  • 7
  • This is more along the lines of what I was thinking in my comments on the question. – squillman Mar 04 '21 at 13:38
  • @squillman Yeah. IMO, this is the best way to approach this problem – Near Mar 04 '21 at 13:44
  • I am trying to digest this .. I created sandbox here. https://codesandbox.io/s/fluent-ui-example-forked-2xtbt?file=/example.js:277-286 – DevÁsith Mar 04 '21 at 13:52
  • @InfoÁsith Added a working codesandbox link in the answer. Please check – Near Mar 04 '21 at 14:44
  • @Near Thank you for response. I checked your sandbox URL, but I wanted to create icon component dynamically. here I created another sandbox to simplify the problem https://codesandbox.io/s/fluent-ui-example-forked-rrk4l?file=/example.js – DevÁsith Mar 04 '21 at 17:11
  • You can never use any icon without importing it into your file. So, there's no point in doing it dynamically without you importing the icon components in the file you want to use it – Near Mar 04 '21 at 17:23
  • @Near . It has to do dynamically in my requirement. i was looking something similar like https://reactjs.org/docs/code-splitting.html#reactlazy – DevÁsith Mar 04 '21 at 18:26