扩展 React 风格的组件
Extending a React Styled Component
我正在使用 Styled Components 运行ning v5,但在扩展样式化组件时遇到了一些问题。我将在下面显示代码。
我有一个标题组件,其中 returns 一个 React.FC 包含一个 StyledHeading。然后,在另一个文件中,我试图扩展标题。然而,这样做时,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>
);
};
*如您所见,我将 as
和 forwardedAs
设置为可选 属性(因为我不知道组件应该如何运行,这只是一个示例)。
此外,您可以查看我所做的 code sample(如果您单击以更新 url 示例,您将看到记录该组件两次)。
最后,您可以阅读更多相关信息 here。
我正在使用 Styled Components 运行ning v5,但在扩展样式化组件时遇到了一些问题。我将在下面显示代码。
我有一个标题组件,其中 returns 一个 React.FC 包含一个 StyledHeading。然后,在另一个文件中,我试图扩展标题。然而,这样做时,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>
);
};
*如您所见,我将 as
和 forwardedAs
设置为可选 属性(因为我不知道组件应该如何运行,这只是一个示例)。
此外,您可以查看我所做的 code sample(如果您单击以更新 url 示例,您将看到记录该组件两次)。
最后,您可以阅读更多相关信息 here。