#reactjs #styled-components
#reactjs #styled-components
Вопрос:
Недавно я начал использовать стилизованные компоненты вместе с React, и я не уверен, правильно ли я справляюсь с конкретным случаем, который продолжает повторяться.
Допустим, у меня есть очень простой компонент, такой как a Label
, который нуждается только в очень стилях и некотором заданном контенте. Теперь я бы справился с этим следующим образом:
import React from "react";
import styled from "styled-components";
export type Props = {...};
export const Impl = styled.span`
display: inline-block;
padding: 0 4px;
...
`;
export const Label: React.FC<Props> = ({ text }) => <Impl>{ text }</Impl>;
Я нахожу целесообразным определить базовые компоненты, такие как Impl
first, только для стилей, а затем другой компонент, который берет реквизит и использует этот стилизованный компонент.
Есть ли более короткий способ сделать и то, и другое только в одном компоненте? Я надеялся на что — то вроде …
export const Label = styled.span<Props>=`
...styles...
`({ label }) = { label };
… но это, похоже, не работает.
Комментарии:
1. Вы могли бы использовать
.attrs()
для выбораchildren
реквизита, но посмотрите, сможете ли вы выяснить, как применять типы:const Label = styled.span.attrs({ children: (props) => props.text })`display: inline-block;`;
2. Похоже, что последние стилизованные компоненты
.attrs
используются в функции:styled.span.attrs((props: Props) => ({ children: props.text }))`display: inline-block;`
Ответ №1:
Один из способов, которым вы могли бы это сделать, — использовать styled
factory и просто встроить свой компонент — хотя это инвертирует отношение в том смысле, что вы не используете a styled.span
, а просто стилизуете свой собственный компонент с помощью className
generated by styled-components
. Это также означает, что вам нужно включить className?
в тип вашего реквизита или использовать тип утилиты, чтобы добавить его.
type Props = {
text: string;
className?: string;
};
const Label = styled(({ text, className }: Props) => (
<span className={className}>{text}</span>
))`
display: inline-block;
padding: 0 4px;
color: red;
`;
export default function App() {
return (
<>
<Label text="foo" />
</>
);
}
Вы также можете предпочесть это:
const Label = styled(({ text, ...props }: Props) => (
<span {...props}>{text}</span>
))`
display: inline-block;
padding: 0 4px;
color: red;
`;
или с типом утилиты:
type SCP<T> = T amp; { className?: string };
type Props = {
text: string;
};
const Label = styled(({ text, ...props }: SCP<Props>) => (
<span {...props}>{text}</span>
))`
display: inline-block;
padding: 0 4px;
color: red;
`;
Комментарии:
1. Вау. Спасибо за ваше время и поддержку, @cbr, я не знал о заводской функции; это выглядит как довольно крутое решение!
2. @JohnGoofy Вы также можете использовать его с любым другим компонентом, который передается
className
дальше 🙂 напримерstyled(Component)