【问题标题】:How to style a nested functional component using styled components如何使用样式化组件设置嵌套功能组件的样式
【发布时间】:2021-04-21 22:02:04
【问题描述】:

我有一个带有以下属性的按钮 - variantloadingdisabled。另外,我有一个按钮组,它接受按钮作为子按钮并将它们与 20px 间隔。像这样的:

从技术上讲,我这里有两个组件。一个<Button /> 和一个<ButtonGroup />。这可以通过编写来实现:

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>

这里的最后一件事也是主要问题是实现按钮的加载状态。或者一般来说,为样式化的组件添加额外的逻辑。因此,我所知道的“最佳”方式是创建一个新的功能组件,然后将其包装在另一个样式中。像这样的:

// 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.
  }
`;

当然,它会起作用,但我不确定这是否是最好的方法。目前,如您所见,我通过调用样式组件 -> 函数组件 -> 样式组件来实现最简单的组件。我不确定它将如何与我的其他组件一起扩展,尤其是命名这些组件。

所以我的问题是,有没有更好、更清洁、更简单的方法来做到这一点?

【问题讨论】:

  • 我不这么认为。这看起来是一种非常常见的嵌套样式方法。
  • “更好”“干净”“简单”是意见,在我看来,你的方法似乎还可以,看不到任何规模问题。
  • @DennisVash 可能有人认为,是的,但我的观点是,为一个简单的任务创建三个组件感觉太冗长了。首先,我调用我的组件StyledButton,然后我创建了一个新组件,它只是Button,最后,我创建了一个新组件,它也是一个基本样式的按钮。很难对这些命名进行推理。另外,当您想在任何 IDE 中查找引用时,它会给您带来困难。如果这是事实上的做事方式,那么我猜 styled-components 不是我的首选。
  • 不确定为什么需要 3 个组件,两个就足够了,因为您已经通过了 className,也许可以尝试添加代码和框
  • @DennisVash 因为否则,我将无法嵌套样式按钮(请参阅我在ButtonGroup 中写的评论。如果仍然不清楚,请告诉我,我会打开一个代码框示例

标签: javascript reactjs styled-components


【解决方案1】:

我没有看到三个组件的原因,对我有用的模式是使用点表示法:

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 对象。

然后在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} .../>

【讨论】:

    猜你喜欢
    • 2020-09-22
    • 2018-07-10
    • 2019-11-08
    • 2020-06-28
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2021-04-13
    • 2021-10-21
    相关资源
    最近更新 更多