0

I stored my social links data on firebase, and now I want to make a <li> list of my social links but the icon object I have here, is not showing me the icons instead it's showing me the elements like: <BsBehance />. It should be displayed as icon, how can I do that?

Firebase data:-

enter image description here

Code:-

import { useEffect, useState } from "react";
import * as ReactIcons from "react-icons/fa";
import MainWrapper from "./MainWrapper";
import classes from "./pages.module.css";

export default function Footer() {
    const [socialLinks, setSocialLinks] = useState([]);

    useEffect(() => {
        const fetchSocilLinks = async () => {
            const res = await fetch(
                "https://mohitdevelops-d64e5-default-rtdb.asia-southeast1.firebasedatabase.app/accounts.json"
            );
            const data = await res.json();
            let loadedData = [];
            for (const keys in data) {
                loadedData.push({
                    url: data[keys].url,
                    icon: data[keys].icon,
                    id: data[keys].id,
                });
            }
            setSocialLinks(loadedData);
        };
        fetchSocilLinks().catch((err) => {
            console.log(err.message);
        });
    }, [socialLinks]);

    console.log(socialLinks);

    return (
        <footer className={classes.footer__wrap}>
            <MainWrapper>
                <p>Connect with me:</p>
                <ul className={classes.social_links}>
                    {socialLinks?.map(({ icon, id, url }) => {
                        const iconLink = icon.split(/\<|\/>/).filter((e) => e)[0];
                        const IconsComponent = ReactIcons[iconLink];
                        return (
                            <li key={id}>
                                <a href={url} target="_blank">
                                    <IconsComponent />
                                </a>
                            </li>
                        );
                    })}
                </ul>                   
            </MainWrapper>
        </footer>
    );
}

And its showing me like this:-

enter image description here

Everything data is coming fine, just need to know how to display an element which is working like an icon.

Mohit
  • 135
  • 10

3 Answers3

1

Since el.icon is a string, it's being displayed as a string. If you want to render the component based on that dynamic string, you need to have an object, where the key name is the string you will get from the server. And the value, can be the component itself.

When you insert a string inside {}, React will render it as a string, even if they're in the < /> format.

And also, try to never use dangerouslySetInnerHTML, since it has high security issues.

Here is a codesanbox, for your above case. Please check this:

Arindam
  • 163
  • 1
  • 13
0

You need to use dangerouslySetInnerHTML like this

<ul className={classes.social_links}>       
       {socialLinks.map((el) => {
            return (
                <li key={el.id}>
                    <a href={el.url} target="_blank">
    <span dangerouslySetInnerHTML={{__html: el.icon}} />
                    </a>
                </li>
            );
        })}
</ul>
Miguel Caro
  • 280
  • 1
  • 4
0

The icon which need to display should be import from the react-icon/bs and that icon name is coming from the firebase data, so it can be import using dynamic import in react.js but for dynamic import you need to handle loading separately, but I have provided easy way.

Need to install react-icon

npm install react-icons --save

And then import all the Icon

import * as ReactIcons from "react-icons/bs";

And add this line of code

  <ul>
    {socialLinks?.map(({ icon, id, url }) => {
      const iconLink = icon.split(/\<|\/>/).filter((e) => e)[0];
      const Compoenent = ReactIcons[iconLink];
      return (
        <li key={id}>
          <a href={url}>
            <Compoenent />
          </a>
        </li>
      );
    })}
  </ul>
  • Im getting error says:- "Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports." AND it's telling me to see the line of in returned statement. – Mohit Dec 01 '22 at 08:15
  • Can you share your entire code snippets in question itself. – Tejashree Surve Dec 01 '22 at 08:53
  • I've updated the code snippet here, please check – Mohit Dec 01 '22 at 09:12
  • Import is wrong --> import * as ReactIcons from "react-icons/fa"; it should be --> import * as ReactIcons from "react-icons/bs" its should be bs becuase the icons coming from the firebase is if BS icon so you need to import bs. – Tejashree Surve Dec 01 '22 at 09:24
  • No I've changed the icons, I'm using "Fa" cause one icon was not available in "Bs" so I chose one list of icons to use.... AND I've changed the to on fireabse, so that's fine for now. – Mohit Dec 01 '22 at 09:27
  • Can you share the firebase data that is exact socialLink object – Tejashree Surve Dec 01 '22 at 09:31
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250042/discussion-between-tejashree-surve-and-mohit). – Tejashree Surve Dec 01 '22 at 09:32