У меня есть массив значков .svg, где у каждого значка есть некоторые свойства, которые мне нужно переопределить:
<svg width = "24" height = "24" viewBox = "0 0 24 24"> ... </svg>
import styled from 'styled-components';
import Github from 'assets/github.svg';
import Facebook from 'assets/facebook.svg';
import Twitter from 'assets/twitter.svg';
...
const icons = [
<Github />,
<Facebook />,
<Twitter />,
...
];
Я хотел бы применить один и тот же стиль для каждой иконки без дублирования кода и использовать CSS-in-JS.
Мое решение до сих пор имеет некоторые проблемы:
// Works but,
// I want to use CSS-in-JS like styled-components
// for easier maintenance
const iconStyle = {
width: 50,
height: 50
};
const SocialBar = () => (
<IconBar as = {FlexBox}>
{icons.map((icon, key) => (
<div key = {key}>{React.cloneElement(icon, iconStyle)}</div>
))}
</IconBar>
);
// Works but,
// there are too many icons
const SocialBar = () => (
<IconBar as = {FlexBox}>
<Github style = {iconStyle} />
<Facebook style = {iconStyle} />
...
</IconBar>
);
И такой стиль компонента svg не будет работать:
// Won't override the width = "24" height = "24" properties
const StyledIcon = styled(Github)`
width: 50;
height: 50;
`;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это один из способов сделать это.
//Github.js
import React from "react";
export default function Github({height, width}) {
return (
<svg width = {width} height = {height} viewBox = "0 0 24 24"> ... </svg>
);
}
Затем, где вы хотите его использовать.
<Github height = {24} width = {24} />
Я не совсем уверен, каков ваш запрос относительно уже имеющихся у вас примеров кода. Вы пытаетесь избежать использования React.cloneElement? Сделайте массив значков функциями, а не элементом jsx. map над ним в версию jsx и применить стили к каждому
const icons = [
Github,
Facebook,
Twitter,
]
buildIcons() {
const style = {
//..
}
return icons.map((icon, idx) => (
<icon style = {style} key = {idx}/>
))
}
Использование индекса в качестве ключа работает, но если вы можете найти другое свойство, уникальное для каждого значка, было бы лучше.
Я пытаюсь стилизовать каждую иконку с помощью css-in-js, и, кстати, ваш код не будет работать, потому что icon должен быть в верхнем регистре, иначе реакция не распознает его.
Ну вот так? cssinjs.org/?v=v10.0.0-alpha.22 Похоже, у jss есть несколько доступных вам HOC
Вы можете обернуть SVG элементом (например, i) и стилизовать любые дочерние элементы svg внутри него с помощью некоторого CSS, определенного внутри styled-component (вы также можете настроить таргетинг на g и path). К сожалению, с SVG довольно сложно работать, поэтому вам мая нужно вручную скопировать/вставить SVG xml в файл JS (если вы используете КРА, вы можете импортировать ReactComponent из SVG).
Рабочий пример (скопируйте/вставьте SVG в файл JS - 1-й пример используется по умолчанию, 2-й пример проходит в реквизитах, 3-й пример проходит в нескольких реквизитах):
Значок/Icon.js (этот компонент принимает стилизованный компонент, сгенерированный className, и любой children, помещенный внутри него)
import React from "react";
import PropTypes from "prop-types";
const Icon = ({ className, children }) => (
<i className = {className}>{children}</i>
);
Icon.propTypes = {
className: PropTypes.string.isRequired,
children: PropTypes.node.isRequired
};
export default Icon;
Значок/index.js (это стилизует компонент Icon выше, а затем стилизует children)
import styled from "styled-components";
import Icon from "./Icon";
const StyledIcon = styled(Icon)`
margin: 0 20px;
svg {
fill: ${({ fill }) => fill || "#03a9f3"};
height: ${({ dimension }) => dimension || "50px"};
width: ${({ dimension }) => dimension || "50px"};
}
`;
export default StyledIcon;
Как это помогает? Как я могу применить его к массиву значков? Это похоже на применение встроенного стиля, поэтому мне нужно создать функцию для каждой иконки.