Обычно я бы использовал значки материалов пользовательского интерфейса, импортировав их напрямую в соответствии с инструкциями Material-UI.
Но у меня есть текстовый тег, который является фактическим именем значка (например, calendar_view_day
), и мне нужно динамически получить и отобразить компонент значка из него.
Как я могу что-то вроде:
render() {
return (
<Icon name = "calendar_view_day" color = "primary" />
)
}
Вместо:
render() {
return (
<CalendarViewDay color = "primary" /> // Imported by name
)
}
Итак, я сильно переосмыслил это.
Оказывается, material-ui
включает в себя компонент значка, который позволяет вам это делать... и сам конвертирует имена, поэтому принимает змею, паскаль и другие варианты. ОСТОРОЖНО, это значительно увеличит размер пакета, как указано в комментариях. Если вы ограничены в размере пакета, вам придется использовать другой подход к обслуживанию значков SVG откуда-то!
import Icon from '@material-ui/core/Icon'
...
render() {
return (
<Icon>{props.iconName}</Icon>
)
}
Создайте функцию для:
... Затем используйте компонент Material-UI Icon.
Вот код:
import Icon from '@material-ui/core/Icon'
function upperFirst(string) {
return string.slice(0, 1).toUpperCase() + string.slice(1, string.length)
}
function fixIconNames(string) {
const name = string.split('_').map(upperFirst).join('')
if (name === '3dRotation') {
return 'ThreeDRotation'
} else if (name === '4k') {
return 'FourK'
} else if (name === '360') {
return 'ThreeSixty'
}
return name
}
...
render() {
const iconName = fixIconNames(props.iconName)
return (
<Icon>{props.iconName}</Icon>
)
}
Спасибо @Navid, добавил к моему ответу предупреждение о вреде для здоровья.
В этом решении используются значки шрифтов вместо значков svg. Требует загрузки используемого шрифта. См.: material-ui.com/components/icons/#icon-font-icons
«Правильный ответ» печатает для меня только строку props.iconName, не показывает фактическую иконку.
@jonasRosenvist, вам также нужно включить ссылку в свой код: <link rel = "stylesheet" href = "fonts.googleapis.com/icon?family=Material+Значки" />
это решение сработало для меня - <Icon>сохранить</Icon>; Имя значка должно быть в нижнем регистре без суффикса «Значок». Что-то вроде ChevronRight — нужно изменить на chevron_right. Вы импортировали файл CSS material_icon в index.js
Как указано в комментариях к ответу Кларк выше, решение, использующее компонент Icon, будет использовать шрифтовую версию значков Material-UI, которая не содержит полного набора значков.
Использование того же метода для получения правильного имени значка (позаимствованного из Кларк) в сочетании с React.createElement делает свое дело. Я сделал это в TypeScript, в ванильном javascript это еще проще. Вот компонент в версии TS (dynamicIcon.tsx), также доступный в это репо:
import * as React from 'react';
import * as Icons from '@material-ui/icons/';
type IconType = typeof import('@material-ui/icons/index');
interface DynamicIconProps {
iconName: string,
className: string
}
function upperFirst(string:string) {
return string.slice(0, 1).toUpperCase() + string.slice(1, string.length)
}
function fixIconNames(string:string) {
const name = string.split('-').map(upperFirst).join('')
if (name === '3dRotation') {
return 'ThreeDRotation'
} else if (name === '4k') {
return 'FourK'
} else if (name === '360') {
return 'ThreeSixty'
}
return name;
}
export default class DynamicIcon extends React.Component<DynamicIconProps> {
constructor(props: DynamicIconProps) {
super(props);
}
render() {
return React.createElement(Icons[fixIconNames(this.props.iconName)! as keyof IconType], {className: this.props.className});
}
}
Молодцы, что предоставили решение TS. Но создание элемента никогда не было проблемой - это размер пакета. Я не использую TS, но, насколько я понимаю, для того, чтобы он работал, он все равно должен импортировать каждую иконку в пакет (проверьте create-react-app.dev/docs/analyzing-the-bundle-size).
импорт всего модуля Значок из материал-пользовательский интерфейс разрешит функциональность, но взорваться станет комплектом! Вы можете проанализировать размер пакета через Официальное руководство React