如何将普通React组件转为Styled Component并继承其他样式组件样式?
问题:Styled Components 实现无代码重复的样式继承
我正在使用Styled Components样式框架,现有如下普通React组件:
const SelectButton = ({className,children, ...rest}) => { return ( <select className = {className}{...rest}> {children} </select> ); }
我希望通过调用styled()函数将该组件转为Styled Component,因此已为SelectButton的DOM元素添加了className属性:
export const StyledSelectButton = styled(SelectButton);
但我不想在此Styled Component中编写CSS,而是希望从另一个样式组件StyledButton.js继承样式,其CSS属性如下:
export const StyledButton = styled(Button).attrs(({ type }) => ({ type: type || "button", }))` display: inline-block; height: auto; padding: 0.8rem 2rem; border: none; border-radius: 6px; font-weight: 500; font-size: 1.6rem; text-decoration: none; text-transform: capitalize; cursor: pointer; overflow: hidden; background-color: ${({ primary }) => (primary ? "#646ff0" : "#cccdde")}; color: ${({ primary }) => (primary ? "white" : "#646681")}; .__select { color: #585858; font-family: Poppins; padding: 1rem; border: none; background-color: #cccdde; width: 150px; cursor: pointer; }; `
我曾尝试直接复制代码实现,但存在代码重复问题:
export const StyledSelectButton = styled(SelectButton)` display: inline-block; height: auto; padding: 0.8rem 2rem; border: none; border-radius: 6px; font-weight: 500; font-size: 1.6rem; text-decoration: none; text-transform: capitalize; cursor: pointer; overflow: hidden; background-color: ${({ primary }) => (primary ? "#646ff0" : "#cccdde")}; color: ${({ primary }) => (primary ? "white" : "#646681")}; &__select { color: #585858; font-family: Poppins; padding: 1rem; border: none; background-color: #cccdde; width: 150px; cursor: pointer; } `
请问如何实现无代码重复的样式继承?
解决方案
方法1:提取共享样式片段到变量
把StyledButton里的通用CSS抽成单独的模板字符串变量,在两个组件里复用:
// 定义共享样式 const sharedButtonStyles = ` display: inline-block; height: auto; padding: 0.8rem 2rem; border: none; border-radius: 6px; font-weight: 500; font-size: 1.6rem; text-decoration: none; text-transform: capitalize; cursor: pointer; overflow: hidden; background-color: ${({ primary }) => (primary ? "#646ff0" : "#cccdde")}; color: ${({ primary }) => (primary ? "white" : "#646681")}; .__select { color: #585858; font-family: Poppins; padding: 1rem; border: none; background-color: #cccdde; width: 150px; cursor: pointer; }; ` // 复用共享样式定义StyledButton export const StyledButton = styled(Button).attrs(({ type }) => ({ type: type || "button", }))` ${sharedButtonStyles} ` // 复用共享样式定义StyledSelectButton export const StyledSelectButton = styled(SelectButton)` ${sharedButtonStyles} `
方法2:直接继承StyledButton的样式
利用Styled Components的样式组合特性,直接把StyledButton的样式注入到StyledSelectButton中:
import { StyledButton } from './StyledButton' export const StyledSelectButton = styled(SelectButton)` ${StyledButton} `
这种方式会自动继承StyledButton里的所有CSS规则,包括动态属性(比如primary相关的样式逻辑)。如果需要调整个别样式,直接在后面追加即可,遵循CSS优先级规则。
方法3:继承attrs属性(可选)
如果StyledButton的.attrs()里的属性(比如默认type)也需要复用,可以单独提取attrs逻辑:
// 提取共享attrs逻辑 const buttonAttrs = (props) => ({ type: props.type || "button", }) // StyledButton使用共享attrs export const StyledButton = styled(Button).attrs(buttonAttrs)` /* 原有样式 */ ` // StyledSelectButton复用attrs和样式 export const StyledSelectButton = styled(SelectButton).attrs(buttonAttrs)` ${StyledButton} `
内容的提问来源于stack exchange,提问作者web dev
相关产品推荐
相关产品推荐

