我有这种结构:
<Wrapper activeTextColor="red">
<Text active={true}>Text 1</Text>
<Text active={false}>Text 2</Text>
</Wrapper>
样式化的组件应如下所示:
const Text = styled.p``;
const Wrapper = styled.div`
${Text} {
${props =>
props.activeTextColor &&
css`
/* How to make color red based on "active" attribute of Text element? */
`}
}
`;
如何在此处从父母的样式组成部分访问孩子的道具?
这里是live example
答案 0 :(得分:1)
您不能(据我所知)。但是您可以从子组件访问父对象的道具(反之亦然)。这似乎可以完成您想要做的事情。
简短答案:
您必须将父属性传递给子组件。
在父组件<Wrapper />
中,您必须克隆孩子并将activeTextColor
传递给孩子:
const StyledWrapper = styled.div``;
class Wrapper extends React.Component {
render() {
const { children, activeTextColor } = this.props;
return (
<StyledWrapper activeTextColor={activeTextColor}>
{React.Children.map(children, child =>
React.cloneElement(child, {
activeTextColor: activeTextColor
})
)}
</StyledWrapper>
);
}
}
activeTextColor
组件现在可以访问active
和Text
。
const Text = styled.p`
${props => css`
color: ${props.active ? activeTextColor : "#000"};
`}
`;
另一个选项:
在上述情况下,使用ThemeProvider / ThemeConsumer可能更有意义。如果您知道activeTextColor
将是红色的(也许您正在处理设计令牌),请使用以下方法访问活动颜色:
${props => css`
background: ${props.active ? props.theme.activeTextColor : '#000'};
`}
详细答案(以及为什么有人要这么做):
这扩展了上面的简短答案。在某些时候,您可能需要访问父组件中的父道具,以及子组件中的子道具和父道具。
一个真实的例子就是Tabs之类的东西。我有两种不同的Tab样式/变体,Tabs
容器组件和Tab
都需要根据自己的道具使用自己的样式。它是一个用两种不同方式设置样式的组件。
嵌套样式化的组件无效。因此,您最终会遇到这样的事情。
const StyledTabs = styled.div`
display: flex;
justify-content: flex-start;
${props =>
props.variant === "wizard" &&
css`
justify-content: space-between;
`}
`;
const StyledTab = styled.p`
font-size: 14px;
white-space: nowrap;
font-family: sans-serif;
border: 1px solid #ddd;
padding: 15px;
${props => css`
background: ${props.active ? "#fff" : "#f6f6f6"};
`}
${props =>
props.variant === "box" &&
css`
& {
border-right: 0 none;
&:last-child {
border-right: 1px solid #ddd;
}
border-top: ${props.active
? "2px solid lightseagreen"
: "1px solid #ddd"};
border-bottom: ${props.active ? "none" : "1px solid #ddd"};
}
`}
${props =>
props.variant === "wizard" &&
css`
& {
margin-right: 20px;
text-align: center;
line-height: 40px;
height: 40px;
width: 40px;
border-radius: 50%;
color: ${props.active ? "#fff" : "#000"};
${props.active && "background: lightseagreen"};
}
`}
`;
class Tabs extends React.Component {
render() {
const { children, variant } = this.props;
return (
<StyledTabs variant={variant}>
{React.Children.map(children, child =>
React.cloneElement(child, {
variant: variant
})
)}
</StyledTabs>
);
}
}
class Tab extends React.Component {
render() {
const { children, variant, active } = this.props;
return (
<StyledTab variant={variant} active={active}>
{children}
</StyledTab>
);
}
}
const App = () => (
<div>
<Tabs variant="box">
<Tab active={true}>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</Tabs>
<Tabs variant="wizard">
<Tab active={true}>Step 1</Tab>
<Tab>Step 2</Tab>
<Tab>Step 3</Tab>
</Tabs>
</div>
);
render(<App />, document.getElementById("root"));
完整示例: https://codesandbox.io/s/upbeat-thunder-wfo2m
styled-component的GitHub上的相关问题: https://github.com/styled-components/styled-components/issues/1193
关于StackOverflow的问题很多,但我认为没有很多明确的答案: react-native with styled-components parent prop How to style a child component from a parent styled component, considering passed props
答案 1 :(得分:0)
const Text = styled.p
颜色:$ {props => props.active吗? “ red”:“ palevioletred”}; ;