扩展React样式的组件

问题描述

我正在运行样式组件的v5,并且在扩展样式组件时遇到一些问题。我将在下面显示代码

我有一个heading组件,该组件返回一个包含Styledheading的React.FC。然后,在另一个文件中,我尝试扩展标题。但是,执行此操作时,heading组件似乎甚至没有运行。我在组件中放了一个控制台日志,它没有渲染。

标题

import React from 'react';
import styled,{ css } from 'styled-components';

import { font,fontSize,color,breakpoint } from 'theme';

interface Props {
  as: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
  appearas?: 'h1' | 'h1-jumbo' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
  align?: 'left' | 'center' | 'right';
  className?: string;
}

const heading: React.FC<Props> = ({ as,appearas = as,align = 'left',className,children }) => {
  const jumbo = appearas === 'h1-jumbo';

  console.log('in heading'); // Runs when not extending,doesn't run when extending

  return (
    <Styledheading as={as} appearas={appearas} align={align} jumbo={jumbo} className={className}>
      {children}
    </Styledheading>
  );
};

const H1Styles = css<Props & { jumbo?: boolean }>`
  font-size: ${({ jumbo }) => (jumbo ? fontSize('xl') : fontSize('lg'))};
  text-align: ${({ jumbo,align }) => (jumbo ? 'center' : align)};

  @media (max-width: ${breakpoint('sm')}) {
    font-size: ${({ jumbo }) => jumbo && fontSize('lg')};
  }
`;

const Styledheading = styled.div<Props & { jumbo?: boolean }>`
  font-family: ${font('bold')};
  line-height: 1.25;
  margin: 0;
  text-align: ${({ align }) => align};
  white-space: pre-wrap;

  ${({ appearas }) => appearas === 'h1' && H1Styles}
  ${({ appearas }) => appearas === 'h1-jumbo' && H1Styles}
`;

export default heading;

用法

// Renders an H2 but doesn't process appearas or run console log
<Styledheading as="h2" appearas="h1-jumbo">TEST</Styledheading>

// Renders an H2,appearas works,and console log runs
<heading as="h2" appearas="h1-jumbo>TEST>/heading>

const Styledheading = styled(heading)`margin-bottom: 1000px;`;

任何建议都将是巨大的,因为我目前感到困惑。谢谢!

解决方法

那是因为您的StyledHeading正在包装另一个组件,并且您需要使用forwardedAs而不是as,例如:

<StyledHeading forwardedAs="h2" appearAs="h1-jumbo">
   TEST
</StyledHeading>

<Heading as="h2" appearAs="h1-jumbo">
   TEST
</Heading>

要使上述代码有效,您需要在Props界面以及Heading组件中进行一些更改:

export interface Props {
  as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
  forwardedAs?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
  appearAs?: "h1" | "h1-jumbo" | "h2" | "h3" | "h4" | "h5" | "h6";
  align?: "left" | "center" | "right";
  className?: string;
}

const Heading: React.FC<Props> = ({
  as,forwardedAs,appearAs = as || forwardedAs,align = "left",className,children,}) => {
  const jumbo = appearAs === "h1-jumbo";

  console.log("in heading"); // Runs when not extending,doesn't run when extending

  return (
    <StyledHeading
      as={as}
      forwardedAs={forwardedAs}
      appearAs={appearAs}
      align={align}
      jumbo={jumbo}
      className={className}
    >
      {children}
    </StyledHeading>
  );
};

*如您所见,我将asforwardedAs设置为可选属性(因为我不知道组件的行为,这只是一个示例)。

此外,您可以检查我所做的此code sample(如果单击以更新url示例,则会看到两次记录该组件)。

最后,您可以了解有关此here的更多信息。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...