在 React 中使用 Typescript 实现 Styled-components

介绍

Styled-components 是一个用于 React 应用程序的样式库,它提供了根据收到的 props 灵活定义样式的功能。本文的目的是介绍该库的工作原理、如何为传递的 props 定义类型以及如何扩展样式。

设置

将库添加到应用程序:

yarn add styled-components --dev

React 结构

使用 styled-components 的样式定义遵循以下格式:

import styled from "styled-components";

const StyledComponent = styled.htmlElement`
  // css properties
`;

const Component = () => (
  
);

export default Component;

上述内容包含以下内容:

  • 导入样式:使用库进行样式设计所必需的导入
  • StyledComponent:使用导入的样式定义组件的 css 属性
  • htmlElement:定义html元素的类型,比如div,button……
  • React 示例

    下面,我将提供一个文本组件的简单示例(使用较少的 props 以保持示例简洁)。其想法是应用上面提到的结构并演示 prop 传递的工作原理:

    import styled from "styled-components";
    
    const StyledText = styled.span`
      color: ${(props) => (props.$color ? props.$color : "#000")};
      font-size: ${(props) => (props.$fontSize ? props.$fontSize : "16px")};
    `;
    
    const Text = ({
      children,
      color,
      fontSize,
    }) => (
      
        {children}
      
    );
    
    export default Text;

    对于 Text 组件,可以传递三种类型的 props:`children`、`color` 和 `fontSize`。第一个定义要显示的文本,而第二个和第三个与样式有关。由于只有后两个与样式有关,因此只有它们作为 props 传递给 `StyledText`。在这种情况下,props 以 `$` 为前缀,以避免因传递无法识别它们的 DOM 元素的 props 而导致控制台错误。与组件对应的 html 元素定义为 `styled.span`。

    在 const StyledText 中,根据传入的 props 定义属性,如果提供了 $color 则设置颜色,否则默认为 #000,如果提供了 $fontSize 则设置字体大小,否则默认为 16px。

    因此,组件使用 lib 进行定义。示例中使用了名称“StyledText”,但该名称可以自定义。

    使用 Typescript 进行 React 结构

    从上面在“React 结构”中定义的结构开始,以下是具有类型定义的格式:

    import styled from "styled-components";
    
    interface StyledComponentType {
      // types definition
    }
    
    const StyledComponent = styled.htmlElement`
      // css properties
    `;
    
    const Component = () => (
      
    );
    
    export default Component;

    上面,接口在 `styled.htmlElement` 之后定义,名称为 `StyledComponentType`。在 `接口 StyledComponentType` 内部,定义了类型。

    使用 Typescript 进行 React 的示例

    现在,我将类型定义添加到“React 示例”中的示例中:

    import styled from "styled-components";
    
    interface StyledTextProps {
      $color?: string;
      $fontSize?: string;
    }
    
    interface TextProps {
      children: React.ReactNode;
      color?: string;
      fontSize?: string;
    }
    
    const StyledText = styled.span`
      color: ${(props) => (props.$color ? props.$color : "#000")};
      font-size: ${(props) => (props.$fontSize ? props.$fontSize : "16px")};
    `;
    
    const Text = ({
      children,
      color,
      fontSize,
    }: TextProps) => (
      
        {children}
      
    );
    
    export default Text;

    在上面的例子中,组件的类型在 `TextProps` 中定义,而 styled-components 的类型在 `',根据每个地方传递的 props。

    扩展样式

    该库允许的另一个功能是创建一个从另一个组件继承样式的组件。当你想要彼此略有不同的类似组件,但又不想通过传递 props 为不同的属性提供太多灵活性时,这很有用。

    import styled from "styled-components";
    
    const StyledComponentA = styled.htmlElement`
      // A css properties
    `;
    
    const StyledComponentB = styled(StyledComponentA)`
      // B css properties
    `;
    
    const Component = () => (
      <>
        
        
      
    );
    
    export default Component;

    上面,`styledComponentB` 继承了为 `styledComponentA` 定义的属性,并且在 `StyledComponentB` 中写入的任何属性都会添加更多属性。如果 `styledComponentA` 已经定义了相同类型的属性,它将覆盖它。

    扩展样式示例

    现在,我将展示一个具有两个按钮的样式扩展的示例,它们的填充有所不同,但此属性并不灵活,每个按钮都有预先定义的。

    import styled from "styled-components";
    
    const StyledButtonA = styled.button`
      border: 2px solid #000;
      cursor: pointer;
      padding: 10px 12px;
    `;
    
    const StyledButtonB = styled(StyledButtonA)`
      padding: 15px 20px;
    `;
    
    const Buttons = () => (
      <>
        ButtonA
        ButtonB
      
    );
    
    export default Buttons;

    在上面的例子中,`StyledButtonA` 定义了三个属性:`border`、`cursor` 和 `padding`。`StyledButtonB` 使用相同的属性,因为它通过 `styled(StyledButtonA)` 扩展了 `StyledButtonA` 的样式,但 padding 除外,因为在 `StyledButtonB` 内部定义了不同的属性。

    结论

    本文的目的是解释 styled-components 库如何在使用 TypeScript 的 React 应用程序中工作,涵盖它的用法、与之相关的类型的定义以及有关样式扩展的部分。

    对于那些想要了解更多有关该库的人,这里是文档的链接。