如何在styled-components中选择父组件变体为子组件设置上下文样式?
解决方案
你假设的写法调整后即可实现,不需要透传props,以下是两种常用的稳定实现方案:
方案1:附加状态属性(推荐,子组件内定义样式)
通过attrs给父组件绑定状态对应的自定义属性,即可在子组件的选择器中直接匹配对应状态:
import styled, { css } from 'styled-components'; const Child = styled.div.attrs<{ editing?: boolean }>(props => ({ 'data-editing': props.editing ?? false }))<{ editing?: boolean }>` ${props => props.editing && css`/* 原有Child的editing样式 */`} ` const NoteWrapper = styled.div.attrs<{ compact?: boolean }>(props => ({ 'data-compact': props.compact ?? false }))<{ compact?: boolean }>` ${props => props.compact && css`/* 原有NoteWrapper的compact样式 */`} ` const Note = styled.input` /* 同时匹配两个父组件的激活状态 */ ${Child}[data-editing="true"] ${NoteWrapper}[data-compact="true"] & { /* 上下文样式写在这里 */ padding: 4px 8px; background: #fffbeb; border-radius: 2px; } `
该方案无需修改组件嵌套逻辑,不管层级多深都不需要透传任何状态props,性能稳定无额外开销。
方案2:父组件内定义上下文样式
如果组件关联性极强,也可以直接把上下文样式写在父组件的条件样式块中,无需额外加属性:
const Child = styled.div<{ editing?: boolean }>` ${props => props.editing && css` /* 原有Child的editing样式 */ ${NoteWrapper} { ${props => props.compact && css` ${Note} { /* 上下文样式写在这里 */ padding: 4px 8px; background: #fffbeb; border-radius: 2px; } `} } `} `
关于你提到的写法说明
你设想的${Child.editingClass}形式默认不可用,styled-components不会自动为组件的每个状态prop生成独立的类名常量,需要你手动通过attrs绑定状态标识才能实现类似的匹配效果。
内容的提问来源于stack exchange,提问作者Bijay Shrestha
相关产品推荐
相关产品推荐

