Вызов компонента через реквизит в ReactJS

Я создаю компонент-оболочку для значков, которые импортирую с помощью react-icons. Вот пример того, как это выглядит сейчас:

import { FaTwitter as Twitter} from 'react-icons/fa'
import { Icon } from './elements 

<Icon>
 <Twitter />
<Icon>

Теперь это работает именно так, как я хочу, но я хотел бы упростить код. В идеале я бы хотел, чтобы это выглядело/работало так:

<Icon name='twitter' />

есть идеи как это сделать?


ПРИМЕЧАНИЕ: Если это поможет, вот текущий код для моего компонента Icon:

export const Icon = props => <IconBase {...props} />

Компонент <IconBase> — это всего лишь несколько стилей из styled-components.


ОБНОВИТЬ

Я просто хочу отметить, что пример Twitter — это всего лишь пример. Я ищу решение, которое будет работать независимо от того, какое имя я передам компоненту <Icon>. Итак, другими словами, все следующее (и многое другое) будет работать:

<Icon name = "Facebook" />
<Icon name = "Search" />
<Icon name = "Menu" />

Каждый из них будет эквивалентен:

<Icon><Facebook /></Icon>
<Icon><Search /></Icon>
<Icon><Menu /></Icon>

Другими словами, независимо от того, какую иконку я вытащу из react-icons, она будет правильно отображаться по отношению к реквизиту name.

Вы можете создать объект словаря, который указывает на компонент, который вы хотите отобразить как Icon дочерние элементы. что-то вроде {twitter: <Twitter />}

JohnSnow 17.06.2019 21:05

Является ли твиттер функцией?

user-9725874 17.06.2019 21:06

@Jesse Твиттер — это компонент. Таким образом, <Icon name = "twitter"/> будет эквивалентно <Icon><Twitter /></Icon>

Moshe 17.06.2019 21:12

@JohnSnow Я не понимаю, как это будет работать. Не могли бы вы показать мне более подробный пример?

Moshe 17.06.2019 21:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
598
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, что-то вроде этого удовлетворило бы ваше условие.

const App = () => <Icon name = "twitter" />;

const dict = { twitter: <Twitter /> };

const Icon = ({ name }) => <IconBase>{dict[name]}</IconBase>;

Спасибо за пример. Однако, чтобы этот метод работал, мне нужно создать новую словарную запись для каждого значка, который я хочу использовать — Facebook, Youtube, MenuIcon, значок поиска и т. д.? Есть ли способ обобщить это, чтобы оно автоматически работало независимо от того, какое имя я передаю?

Moshe 17.06.2019 21:22

Что ж, вы можете просто передать компонент в качестве реквизита имени и указать его как {props.name} внутри вашего компонента Icon. Но если ваше ограничение заключается в том, что вы хотите использовать name = "{string}", то я не думаю, что есть другой способ.

JohnSnow 17.06.2019 21:26

Если вы хотите использовать String в качестве реквизита, вам придется использовать словарь. Если вы передадите фактический компонент, то вы этого не сделаете. Вы также можете использовать шаблон Render Prop. <Icon render = {(Component)=> <Component />} /> Все они одинаковые...

JohnSnow 17.06.2019 21:36

Спасибо -- в итоге я остановился на этом варианте: export const Icon = props => <IconBase><props.name /></IconBase>;. Что я делаю следующим образом: <Icon name = {Facebook} />

Moshe 17.06.2019 21:49
Ответ принят как подходящий

Что насчет этого?

// definition:
const Icon = (props) => <SomeIconWrapper><props.glyph /></SomeIconWrapper>;
// usage:
<Icon glyph = {Twitter} />

Это очень просто и гибко, нет необходимости в каком-либо словаре или что-то в этом роде.

Да, но в примере он использует String в качестве реквизита, а не Component. Это требование. Я думал, что вся проблема заключается в преобразовании строки для ссылки на компонент.

JohnSnow 17.06.2019 21:27

Я бы предпочел использовать String, но я открыт для использования Component.

Moshe 17.06.2019 21:36

Другие вопросы по теме