如何使用样式组件设置嵌套功能组件的样式 [英] How to style a nested functional component using styled components
问题描述
我有一个带有以下道具的按钮 - variant
、loading
和 disabled
.另外,我有一个按钮组,它接受按钮作为子项并将它们间隔 20px.像这样:
I have a button with the following props - variant
, loading
, and disabled
. Plus, I have a button group that accepts buttons as children and gaps them with 20px. Something like this:
从技术上讲,我在这里有两个组成部分.一个 和一个
.这可以通过编写来实现:
Technically speaking, I have two components here. A <Button />
and a <ButtonGroup />
. This would be achievable by writing:
const Button = styled.button`
// css implementation
:disabled {
opacity: 0.5;
}
`;
const ButtonGroup = styled.button`
// css implementation
${Button} + ${Button} {
margin-inline-start: 20px;
// PS - I'm aware I could use the `gap` property, but I'm not specifically talking about this example, but in general.
}
`;
// Usage
<ButtonGroup>
<Button ... />
<Button ... />
</ButtonGroup>
最后一件事也是这里的主要问题是实现按钮的加载状态.或者一般来说,向样式化组件添加额外的逻辑.所以最好的"我所知道的方法是创建一个新的功能组件,然后将其包装在另一个样式中.像这样:
The last thing and the main issue here is to implement the loading state of the button. Or in general, adding extra logic to the styled component. So the "best" way I know of is to create a new functional component and then wrap it inside another styled. Something like this:
// Button.tsx
const StyledButton = styled.buton`...`;
const Button = (props) => {
return (
<StyledButton className={props.className}>
{props.loading && <LoadingSpinner />}
{props.children}
</StyledButton>
);
}
export default styled(Button)``; // It's needed for for nested styling.
...
// ButtonGroup.tsx
const ButtonGroup = styled.button`
// css implementation
${Button} + ${Button} {
margin-inline-start: 20px;
// PS - I'm aware I could use the `gap` property, but I'm not specifically talking about this example, but in general.
}
`;
当然可以,但我不确定这是否是最好的方法.目前,如您所见,我是通过调用样式化组件来实现的 ->功能组件 ->最简单组件的样式组件.我不确定它将如何与我的其他组件一起扩展,尤其是命名这些组件.
It will work, of course, but I'm not sure if it's the best way. Currently, as you can see, I did it by calling styled component -> function component -> styled component for the simplest component. I'm not sure how it will scale with my other components, especially naming these components.
所以我的问题是,有没有更好、更干净、更简单的方法来做到这一点?
So my question is, is there a better, cleaner, simpler way of doing this?
推荐答案
我没有看到三个组件的原因,对我有用的模式是使用点表示法:
I don't see a reason for three components, a pattern that works for me is using dot notation:
const StyledButton = styled.button``;
const Button = (props) => {
return (
<StyledButton className={props.className}>
{props.loading && <LoadingSpinner />}
{props.children}
</StyledButton>
);
};
Button.Styled = StyledButton;
export default Button;
通过这种方式,您有一个模式,其中 Component.Styled
(如果可用)将始终保存您可以定位的运行时 CSS-in-JS 对象.
In this way, you have a pattern where Component.Styled
(if available) will always hold the runtime CSS-in-JS object which you can target.
然后在 ButtonGroup
实现中:
import { Button } from "@components";
// You can target the className
const ButtonGroup = styled.div`
${Button.Styled} { ... }
`;
// You can apply styles
styled(Button)
// You can use the component
<Button />
// Or extend style etc
<OtherButton as={Button.Styled} .../>
这篇关于如何使用样式组件设置嵌套功能组件的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!