1

I want to display a list of icons like this website.

I have JSON data that stores the family and the name of the icons. I want to map the JSON to pass the family value and the name value in my component CardItem.

However, I don't know how to map it correctly. Thanks for your help!

import React from "react";
import { CardItem } from "./card";

export const List = () => {
  const data = [
    {
      family: "AntDesign",
      names: ["stepforward", "stepbackward", "forward", "banckward"]
    },
    {
      family: "Entypo",
      names: ["500px", "500px-with-circle", "add-to-list", "add-user"]
    }
  ];

  return (
    <>
      <ul>
        {data.map((data, index) => (
          <li key={index}>
            <CardItem
              family={data.family}
              name={data.names.map((name) => name)}
            />
          </li>
        ))}
      </ul>
    </>
  );
};
7
  • 2
    data.names.map((name) => name ) won't do anything, you should use data.names Commented Dec 14, 2020 at 16:35
  • Do you want a CardItem element by name (meaning merging the two sub-arrays) or a CardItem by first level items? Commented Dec 14, 2020 at 16:35
  • @MetallimaX I want a CardItem by name :) Commented Dec 14, 2020 at 16:37
  • data.names.map(name) => <CardItem key={name} name={name} /> Commented Dec 14, 2020 at 16:40
  • I don't think that nesting the map will behave well as the result will be a list of lists. Commented Dec 14, 2020 at 16:46

2 Answers 2

1

If you wanted to, you could try to reverse-engineer the DOM on that website. Here is the general flow of the DOM on that site:

Files:

  • App.jsx
    • icon_data.json
    • ResultContainer.jsx
      • ResultRow.jsx
        • ResultTitle.jsx
        • ResultList.jsx
          • ResultIcon.jsx

Here is a forkable snippet of the code below:

https://codesandbox.io/s/react-icon-mapping-qfsp5?file=/src/App.jsx

icon_data.json

[
  {
    "family": "AntDesign",
    "names": ["stepforward", "stepbackward", "forward", "backward"]
  },
  {
    "family": "Entypo",
    "names": ["500px", "500px-with-circle", "add-to-list", "add-user"]
  }
]

App.jsx

import React, { useEffect, useState } from "react";
import iconData from "./icon_data.json";
import ResultContainer from "./ResultContainer";

const fetchIconData = () => Promise.resolve(() => iconData);

const App = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetchIconData().then((jsonData) => setData(jsonData));
  }, []);

  return <ResultContainer data={data} />;
};

export default App;

ResultContainer.jsx

import React from "react";
import PropTypes from "prop-types";
import ResultRow from "./ResultRow";

const ResultContainer = (props) => {
  const { data } = props;

  return (
    <>
      {data.map(({ family, names }) => {
        return <ResultRow title={family} icons={names} />;
      })}
    </>
  );
};

ResultContainer.propTypes = {
  data: PropTypes.array.isRequired
};

export default ResultContainer;

ResultRow.jsx

import React from "react";
import PropTypes from "prop-types";
import ResultTitle from "./ResultTitle";
import ResultList from "./ResultList";

const ResultRow = (props) => {
  const { title, icons } = props;

  return (
    <div className="Result-Row">
      <ResultTitle title={title} />
      <ResultList icons={icons} />
    </div>
  );
};

ResultTitle.propTypes = {
  title: PropTypes.string.isRequired,
  icons: PropTypes.array.isRequired
};

export default ResultRow;

ResultTitle

import React from "react";
import PropTypes from "prop-types";

const style = {
  background: "#F66667",
  color: "#FFFFFF",
  padding: "1em",
  margin: "0"
};

const ResultTitle = (props) => {
  const { title } = props;

  return (
    <h2 className="Result-Title" style={style}>
      {title}
    </h2>
  );
};

ResultTitle.propTypes = {
  title: PropTypes.string.isRequired
};

export default ResultTitle;

ResultList.jsx

import React from "react";
import PropTypes from "prop-types";
import ResultIcon from "./ResultIcon";

const style = {
  display: "flex",
  flexDirection: "row"
};

const ResultList = (props) => {
  const { icons } = props;

  return (
    <div className="Result-List" style={style}>
      {icons.map((icon) => (
        <ResultIcon name={icon} />
      ))}
    </div>
  );
};

ResultList.propTypes = {
  icons: PropTypes.array.isRequired
};

export default ResultList;

ResultIcon.jsx

import React from "react";
import PropTypes from "prop-types";

const containerStyle = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  justifyContent: "center",
  padding: "0.5em",
  outline: "thin solid rgb(238, 238, 238)"
};

const iconStyle = {
  fontWeight: "normal",
  fontSize: "2em",
  textAlign: "center"
};

const titleStyle = {
  fontSize: "smaller",
  fontWeight: "normal",
  textAlign: "center",
  margin: "0"
};

const ResultIcon = (props) => {
  const { name } = props;

  return (
    <div className="Result-Icon-Container" style={containerStyle}>
      <span className="Result-Icon" style={iconStyle}>
        ☺
      </span>
      <h4 className="Result-Icon-Name" style={titleStyle}>
        {name}
      </h4>
    </div>
  );
};

ResultIcon.propTypes = {
  name: PropTypes.string.isRequired
};

export default ResultIcon;
Sign up to request clarification or add additional context in comments.

Comments

0

You can do the following,

import React from "react";
import { CardItem } from "./card";

export const List = () => {
  const data = [
    {
      family: "AntDesign",
      names: ["stepforward", "stepbackward", "forward", "banckward"]
    },
    {
      family: "Entypo",
      names: ["500px", "500px-with-circle", "add-to-list", "add-user"]
    }
  ];

  return (
    <>
      <ul>
        {data.map((item, index) => (
          <li key={index}>
            {item.names.map((name) => {
               return <CardItem
                    family={item.family}
                    name={name}
            />

            })
            }
          </li>
        ))}
      </ul>
    </>
  );
};

2 Comments

Thank you so much !!
Don't use index as keys You have a perfectly good key with item.family, and you also forgot to put a key (name) on the inner array.

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.