我有这种结构:
<Wrapper activeTextColor="red">
<Text active={true}>Text 1</Text>
<Text active={false}>Text 2</Text>
</Wrapper>
Styled-components 应该是这样的:
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? */
`}
}
`;
这里如何从父级的样式组件访问子级的 Prop ?
这是一个live example
最佳答案
你不能(据我所知)。但是您可以从子组件访问父组件的 props(反之亦然)。这似乎完成了您正在尝试做的事情。
简答:
您必须将父属性传递给子组件。
在父组件中 <Wrapper />
你将不得不克隆你的 child 并通过 activeTextColor
给 children :
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
将变为红色(也许您正在处理设计 token ),然后使用以下方式访问事件颜色:
${props => css`
background: ${props.active ? props.theme.activeTextColor : '#000'};
`}
详细答案(以及为什么有人想要这样做):
这扩展了上面的简短答案。在某些时候,您可能需要访问父组件中的父属性,以及子组件中的子属性和父属性。
一个真实世界的例子就像 Tabs。我有两种不同样式/变体的选项卡,均带有 Tabs
容器组件和 Tab
根据自己的 Prop 需要自己的风格。它是一种具有两种不同样式的组件。
嵌套 styled-components 是行不通的。所以你最终会得到这样的结果。
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
关于javascript - 如何从 parent 的样式组件访问 child 的 Prop ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57803505/