上面的问题是Button 必须接受来自styled(Button) 的className 属性。然后它需要将其传递给StyledButton:
import * as React from 'react'
import styled from 'styled-components'
const ButtonStyle = styled.span`
// shared styles ...
// props
background: ${props => props.primary ? "red" : "white"};
`
export function Button({ className, label }) {
return <ButtonStyle className={className}>{label}</ButtonStyle>
}
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
export default TomatoButton;
Styled-components 通过为元素分配一个唯一的className 来工作。如果您使用styled.HTMLElement (styled.div, styled.img, ..etc),那么它会自动执行。但是,当您使用 styled 包装 React 组件时,它假定它将接受并手动将 className 分配给组件。
例如:
import * as React from "react";
import styled from "styled-components"
// the result of "RedButton" is <button className="sc-hBEYos dWjUC">{children}</button>
const RedButton = styled.button`
color: red;
`;
// the result of "Example" is <button className="sc-hBEYos dWjUC">Test</button>
const Example = () => <RedButton>Test</RedButton>
当您使用 React 组件时,它必须接受并分配 className 和 children(可能还有其他传入的 props)并手动分配它们:
import * as React from "react";
import styled from "styled-components";
// the result of "Button" is <button className={className}>{children}</button>
const Button = ({ className, children }) => (
<button className={className}>
{children}
</button>
);
// the result of "BlueButton" is <button className="sc-hBEYos dWjUC">{children}</button>
const BlueButton = styled(Button)`
color: blue;
`;
// the result of "Example2" is <button className="sc-hBEYos dWjUC">Test</button>
const ExampleTwo = () => <BlueButton>Test</BlueButton>
如您所见,如果您尝试将组合的 React 组件与其他样式的组件一起包装(您必须继续传递className),则样式化组合的 React 组件可能会变得有点多余和冗长,所以我建议使用 @987654321 @方法。
简而言之,将 styled-components 保持为styled.HTMLElement,如果需要对其进行包装,则使用上面提到的 compose(指其他组件)方法:
import styled from "styled-components";
const Button = styled.button`
color: red;
`;
const BlackBlueButton = styled.div`
background: black;
${Button} {
color: blue;
}
`;
// In short, the result is that the "Button" below gets two classNames, one from
// itself (styled.button) and another from "BlackBlueButton".
const Example = () => (
<BlackBlueButton>
<Button>Test</Button>
</BlackBlueButton>
);
另外,如果您想创建灵活的组件,请查看answer。