javascript - 如何从 parent 的样式组件访问 child 的 Prop ?

标签 javascript css reactjs frontend styled-components

我有这种结构:

  <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>
    );
  }
}

两者都是 activeTextColoractive现在可以从 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 需要自己的风格。它是一种具有两种不同样式的组件。

Tab Example

嵌套 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/

相关文章:

ReactJS typescript 错误Parameter props implicitly has 'any' type

javascript - 在 JSTree 中禁用多项选择不起作用

javascript - 在 JavaScript 中使用异步函数

javascript - 在 Shiny 的应用程序中包含 js/css 脚本

java - 更改 TableCell 中的背景颜色会删除选择颜色,使其难以阅读

rest - 我无法通过 React 调用休息电话

css - React - 垂直对齐文本和图标

javascript - 如何绕过 JavaScript 变量作用域

html - 内容左侧和右侧的水平线特定宽度

javascript - 如何在不同的包含 div 上创建叠加按钮