0

I'm new to react and trying to create a menu bar of sorts. All the similar questions seem to be older or not quite what I need. Regardless, I can't get this to work so please help figuring this out.

I'm using react-icons and would like to dynamically name the component so I can use the icons within this loop but <{val.icon} /> is throwing an error: "'...' expected." What can I do to make this work? I also can't seem to declare variables in a return statement to work around this, or at least I can't figure out how to do so. Any idea?

   const values = [
    { id: 1, text: "Home", icon: "MdHomeFilled" },
    { id: 2, text: "Schedule", icon: "MdEditCalendar" },
    { id: 3, text: "Scores", icon: "MdSportsTennis" },
    { id: 4, text: "Stats", icon: "IoIosStats" }
    ];

return (
    <>
       
            <ul>

                {values.map((val) => (
                    <li onClick={() => setActiveId(val.id)}>
                        <div className={activeId === val.id ? "NavLinkBox selected":"NavLinkBox"}>
                            <div className="navLinkBoxHdr"><{val.icon} /></div>
                            <div className="navLinkBoxCnt">{val.text}</div>
                        </div>
                    </li>
                ))}
            </ul>
0

2 Answers 2

2

You can't just use a component name (i.e. as a string) in order to render a component.

In order to render it, you need to import it like you would regularly, then convert it into a variable with a capitalized name. For example:

import MdHomeFilled from './MdHomeFilled';
import MdEditCalendar from './MdEditCalendar';

export default function App() {
  const values = [
    { id: 1, text: "Home", icon: MdHomeFilled },
    { id: 2, text: "Schedule", icon: MdEditCalendar }
  ];

  return ( 
    <ul>
        {values.map((val) => {
          const IconComponent = val.icon; // This way you can use this field as a component
          return (
            <li key={val.id} onClick={() => setActiveId(val.id)}>
                <div className={activeId === val.id ? "NavLinkBox selected":"NavLinkBox"}>
                    <div className="navLinkBoxHdr"><IconComponent /></div>
                    <div className="navLinkBoxCnt">{val.text}</div>
                </div>
            </li>
          );
        })}
    </ul>
  );
}
Sign up to request clarification or add additional context in comments.

3 Comments

This almost works but it doesn't retain the capitalization. Console shows <mdhomefilled></mdhomefilled> which doesn't link up to the correct icon within the component.
I edited my answer - the component's name casing is significant
yes this works thanks! Now I just have to figure out why the CSS blows up when I do this rather than simply writing it out. Always something when you start out...
0

Use it like this:

const socialArr = [
[
  "Linkedin",
  <TiSocialLinkedinCircular size={30} style={{ color: "grey" }} />,
],
["Github", <AiFillGithub size={25} style={{ color: "grey" }} />],
["Facebook", <BsFacebook size={24} style={{ color: "grey" }} />],
["Twitter", <AiFillTwitterCircle size={25} style={{ color: "grey" }} />],
["Instagram", <AiFillInstagram size={25} style={{ color: "grey" }} />],
["Website", <BsGlobe size={25} style={{ color: "grey" }} />],  ];


{socialArr.map(([name, icon]) => (
      <>
        <div className="web__bottom__tab">
          <h2>{name}</h2>
          <div className="web__input">
            {icon} // here is the icon that will be rendered
            <input type="text" placeholder={name} />
          </div>
        </div>
      </>
    ))}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.