簡體   English   中英

如何從父母的樣式組件訪問孩子的道具?

[英]How to access child's props from parent's styled-component?

我有這樣的結構:

  <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? */
      `}
  }
`;

如何從這里的父母的樣式組件訪問孩子的道具?

這是一個活生生的例子

你不能(據我所知)。 但是您可以從子組件訪問父組件的道具(相反)。 這似乎完成了你想要做的事情。

簡短的回答:

您必須將父道具傳遞給子組件

在父組件<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>
    );
  }
}

現在可以從Text組件訪問activeTextColoractive

const Text = styled.p`
  ${props => css`
    color: ${props.active ? activeTextColor : "#000"};
  `}
`;

另外一個選項:

在上述情況下,使用 ThemeProvider/ThemeConsumer 可能更有意義。 如果您知道activeTextColor將是紅色(也許您正在處理設計令牌),請使用以下命令訪問活動顏色:

${props => css`
  background: ${props.active ? props.theme.activeTextColor : '#000'};
`}

詳細答案以及為什么有人想要這樣做):

這擴展了上面的簡短回答。 在某些時候,您可能需要訪問父組件中的父道具,以及子組件中的子道具和父道具。

一個現實世界的例子是像 Tabs 這樣的東西。 我有兩種不同樣式/變體的選項卡, 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,考慮傳遞的 props

const Text = styled.p`color: ${props => props.active ? "red" : "palevioletred"};`;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM