【问题标题】:styled-components defaultProps样式化组件 defaultProps
【发布时间】:2019-02-13 01:07:27
【问题描述】:

如果我有以下带有 defaultProp 的按钮

export interface IButton {
  variant: 'action' | 'secondary';
}

export const Button = styled('button')<IButton>`
  background-color: #fff;

  ${props =>
    props.variant === 'action' &&
    css`
      color: blue;
    `};

  ${props =>
    props.variant === 'secondary' &&
    css`
      color: gray;
    `};
`;

Button.defaultProps = {
  variant: 'action',
};

有没有办法输入它?当尝试像这样使用它时

<Button>Hello</Button>

Typescript 抱怨没有传递变量,有没有办法用样式化的组件输入 defaultProps?

【问题讨论】:

    标签: typescript styled-components


    【解决方案1】:

    问题在于 TypeScript 3.0 在检查 JSX 元素时对 defaultProps 的支持需要在组件上声明 defaultProps 的类型。改变现有组件的defaultProps 是行不通的,而且我不知道有什么好的方法可以在styled 之类的函数生成的组件上声明defaultProps。 (在某种程度上,这是有道理的:库创建了一个组件并且不希望您修改它。也许库甚至为某些内部目的设置了defaultProps。) kingdaro 的解决方案很好,或者您可以使用包装器组件:

    const Button1 = styled('button')<IButton>`
      background-color: #fff;
    
      ${props =>
        props.variant === 'action' &&
        css`
          color: blue;
        `};
    
      ${props =>
        props.variant === 'secondary' &&
        css`
          color: gray;
        `};
    `;
    
    export class Button extends React.Component<IButton> {
      static defaultProps = {
        variant: 'action'
      };
      render() {
        return <Button1 {...this.props}/>;
      }
    }
    

    【讨论】:

    • 如果我采用方法 TS 抱怨 onClick 类型内在属性上不存在。我错过了什么吗?
    • 请将所有相关代码添加到问题中,我会看看。 (我没有看到 onClick 的用法。)
    【解决方案2】:

    你可以通过解构你的道具来实现你想要的。

    看来你还是得让你的组件知道它的 prop 类型。为此,只需传递所有道具而不破坏它们(参见下面的背景颜色)。

    import styled from "styled-components";
    
    interface IProps {
      variant?: 'action' | 'secondary';
    }
    
    export const Button = styled.div`
      ${(props: IProps) => `background-color: #fff;`}
      ${({ variant = 'action' }) => variant === 'action' ? `color: blue;` : `color: gray;`}
    `;
    

    【讨论】:

      【解决方案3】:

      据我所知,这还不太可能,不幸的是,TS 3.0 中添加的defaultProps 支持并未涵盖(仅适用于普通组件类,我认为功能组件)。如果我在这方面错了,其他人可以随时纠正我。

      不过,还有其他方法可以编写它。以下是我通常的做法:

      export interface IButton {
        variant?: 'action' | 'secondary';
      }
      
      const variantStyles = {
        action: css`
          color: blue;
        `,
        secondary: css`
          color: gray;
        `,
      };
      
      export const Button = styled('button')<IButton>`
        background-color: #fff;
        ${props => variantStyles[props.variant || 'action']};
      `;
      

      【讨论】:

        猜你喜欢
        • 2021-03-27
        • 1970-01-01
        • 2020-09-26
        • 2020-10-27
        • 2020-09-22
        • 2020-10-19
        • 2019-10-27
        • 2021-07-02
        • 2021-01-12
        相关资源
        最近更新 更多