Визуализация динамических компонентов по именам в React

#javascript #html #reactjs #jsx

#javascript #HTML #reactjs #jsx

Вопрос:

Как мне установить пользовательский тег в React?

Каждый импорт представляет собой элемент JSX. Например, GitHub импортируется из файла, который выглядит следующим образом:

 import React from 'react';

const GitHub = () => (
    <svg role="img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" height="1.5rem" width="1.5rem">
        <title>GitHub Icon</title>
        <path d="M171.25 408.36c0 2.06-2.37 3.7-5.37 3.7-3.4.32-5.78-1.33-5.78-3.7 0-2.07 2.38-3.72 5.37-3.72 3.1-.31 5.78 1.36 5.78 3.72zm-32.1-4.65c-.72 2.07 1.34 4.44 4.44 5.06 2.68 1 5.78 0 6.4-2.06.62-2.06-1.34-4.44-4.44-5.37-2.69-.72-5.68.3-6.4 2.37zm45.62-1.71c-3 .72-5 2.68-4.74 5.06.31 2.06 3 3.4 6.09 2.68 3.09-.72 5-2.68 4.74-4.75-.26-2.07-3.09-3.34-6.09-3zM252.7 6.4C109.52 6.4 0 115.09 0 258.27c0 114.47 72.05 212.44 175 246.9 13.21 2.39 17.86-5.77 17.86-12.48 0-6.4-.31-41.7-.31-63.38 0 0-72.26 15.49-87.44-30.76 0 0-11.76-30-28.69-37.78 0 0-23.64-16.21 1.65-15.9 0 0 25.7 2.07 39.84 26.64 22.61 39.84 60.49 28.38 75.26 21.57 2.37-16.52 9.08-28 16.51-34.8-57.68-6.4-115.95-14.75-115.95-114.05 0-28.4 7.84-42.63 24.36-60.8-2.68-6.71-11.46-34.38 2.68-70.1 21.58-6.7 71.23 27.88 71.23 27.88a242.6 242.6 0 0164.83-8.78 242.52 242.52 0 0164.82 8.78s49.65-34.68 71.23-27.87c14.14 35.82 5.37 63.38 2.68 70.09 16.52 18.27 26.63 32.5 26.63 60.8 0 99.6-60.8 107.56-118.5 114.06 9.5 8.16 17.55 23.64 17.55 47.9 0 34.79-.31 77.83-.31 86.3 0 6.7 4.75 14.86 17.86 12.49C442 470.7 512 372.74 512 258.27 512 115.09 395.87 6.4 252.7 6.4zm-152.36 356c-1.35 1-1 3.4.72 5.37 1.65 1.65 4 2.37 5.37 1 1.34-1 1-3.4-.73-5.37-1.65-1.6-4.02-2.32-5.36-.98zm-11.15-8.36c-.73 1.34.31 3 2.37 4 1.65 1 3.72.72 4.44-.73.72-1.45-.31-3-2.37-4-2.07-.6-3.72-.31-4.44.75zm33.44 36.75c-1.65 1.34-1 4.44 1.34 6.4 2.38 2.37 5.37 2.68 6.71 1 1.35-1.34.73-4.44-1.34-6.4-2.27-2.32-5.34-2.63-6.71-.98zm-11.77-15.18c-1.65 1-1.65 3.72 0 6.1 1.65 2.38 4.44 3.4 5.79 2.37 1.65-1.34 1.65-4 0-6.4-1.45-2.37-4.13-3.41-5.79-2.07z"/>
    </svg>
);

export default GitHub;
  

Остальные значки импортируются из соответствующих файлов в том же формате. Теперь я хочу выполнить цикл DATA для визуализации каждого значка.

 import React, { Component } from 'react';

import GitHub from './../assets/GitHub'
import LinkedIn from './../assets/LinkedIn'
import Email from './../assets/Email'


const DATA = [
    {
        href: "...",
        aria: "...",
        icon: GitHub,
        label: "...",
    },
    {
        href: "...",
        aria: "...",
        icon: LinkedIn,
        label: "...",
    },
    {
        href: "...",
        aria: "...",
        icon: Email,
        label: "...",
    }
];

const Button = ({ href, aria, icon, label }) => {
    return (
        <span className="button-container">
            <a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
                <{icon} className="icon"/>
                <span className="icon_title">{label}</span>
            </a>
        </span>
    );
};

class Buttons extends Component {
    render() {
        return (
            <div>
                {DATA.map((props, i) => (
                    <Button {...props} key={i} />
                ))}
            </div>
        );
    }
}

export default Buttons;
  

Строка кода — это то, с чем я сталкиваюсь с трудностями <{icon} className="icon"/> . Я не знаю, как установить пользовательский HTML-тег во время цикла

Кроме того, мы будем признательны за любые другие отзывы. В DATA должен ли я сохранять каждый значок в качестве псевдонима для импорта или вместо этого должен иметь icon: "GitHub" ?

Спасибо!

Комментарии:

1. вы пробовали другие ответы?

2. Да, в настоящее время работаю с вашим решением и пытаюсь сгладить css

3. я добавил работающий пример и проверяю, работают ли два моих решения и решение Николаса Тауэра

Ответ №1:

Вам нужно переименовать его в Icon с большой буквы I (это соглашение отличает пользовательские компоненты от встроенных, подобных <div> ), но в остальном вы используете его так же, как и любой другой компонент:

 const Button = ({ href, aria, icon: Icon, label }) => {
    return (
        <span className="button-container">
            <a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
                <Icon className="icon"/>
                <span className="icon_title">{label}</span>
            </a>
        </span>
    );
};
  

Ответ №2:

Поскольку в React exige имена компонентов пишутся с заглавной буквы, вы могли бы присвоить этот реквизит локальной переменной с именем Icon , а затем использовать его как JSX :

 
const Button = ({ href, aria, icon, label }) => {
   let Icon=icon;
    return (
        <span className="button-container">
            <a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
                <Icon className="icon"/>
                <span className="icon_title">{label}</span>
            </a>
        </span>
    );
};
  

или установите значки в качестве элементов в массиве ДАННЫХ, например :

 const DATA = [
    {
        href: "...",
        aria: "...",
        icon: <GitHub className="icon" />,
        label: "...",
    },
   ...
  

затем визуализируйте это следующим образом :

 const Button = ({ href, aria, icon, label }) => {
    return (
        <span className="button-container">
            <a className="button" href={href} target="_self" aria-label={aria} rel="noopener noreferrer">
                {icon}
                <span className="icon_title">{label}</span>
            </a>
        </span>
    );
};
  

Пожалуйста, проверьте этот пример