【问题标题】:How to pass styles from a child to the parent using styled components如何使用样式化组件将样式从子级传递给父级
【发布时间】:2021-07-10 00:51:49
【问题描述】:

我正在尝试创建一些按钮变体,并决定使用样式化组件来完成此任务。但是,我在尝试将变体按钮从子级传递给包含所有变体的父级时遇到了一些问题。

目前,我有一个导入 Button.js 组件的导航栏。我希望可以选择更改 Navbar.js 中的按钮,如下所示:

<Button default label="Game" />
<Button secondary label="Dictionary" />

但是,在我的 Button.js 文件中,我尝试通过使用道具来切换按钮的样式,但这不起作用。

import React from 'react'
import styled from 'styled-components'

const ButtonStyle = styled.span`
  // shared styles ...
  // props
  background: ${props => props.primary ? "red" : "white"};

`

function Button({ label }) {
  return <ButtonStyle>{label}</ButtonStyle>
}

export default Button

我也尝试过扩展样式,但问题是名称 TomatoeButton 没有传递给 Navbar.js 组件。

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

这不应该取primary属性,改变背景颜色吗?

【问题讨论】:

    标签: css reactjs sass styled-components


    【解决方案1】:

    上面的问题是Button 必须接受来自styled(Button)className 属性。然后它需要将其传递给StyledButton

    import * as React from 'react'
    import styled from 'styled-components'
    
    const ButtonStyle = styled.span`
      // shared styles ...
      // props
      background: ${props => props.primary ? "red" : "white"};
    `
    
    export function Button({ className, label }) {
      return <ButtonStyle className={className}>{label}</ButtonStyle>
    }
    
    const TomatoButton = styled(Button)`
      color: tomato;
      border-color: tomato;
    `;
    
    export default TomatoButton;
    

    Styled-components 通过为元素分配一个唯一的className 来工作。如果您使用styled.HTMLElement (styled.div, styled.img, ..etc),那么它会自动执行。但是,当您使用 styled 包装 React 组件时,它假定它将接受并手动将 className 分配给组件。

    例如:

    import * as React from "react";
    import styled from "styled-components"
    
    // the result of "RedButton" is <button className="sc-hBEYos dWjUC">{children}</button>
    const RedButton = styled.button`
      color: red;
    `; 
    
    // the result of "Example" is <button className="sc-hBEYos dWjUC">Test</button>
    const Example = () => <RedButton>Test</RedButton>
    
    

    当您使用 React 组件时,它必须接受并分配 classNamechildren(可能还有其他传入的 props)并手动分配它们:

    import * as React from "react";
    import styled from "styled-components";
    
    // the result of "Button" is <button className={className}>{children}</button>
    const Button = ({ className, children }) => (
      <button className={className}>
        {children}
      </button>
    );
    
    // the result of "BlueButton" is <button className="sc-hBEYos dWjUC">{children}</button>
    const BlueButton = styled(Button)`
      color: blue;
    `;
    
    // the result of "Example2" is <button className="sc-hBEYos dWjUC">Test</button>
    const ExampleTwo = () => <BlueButton>Test</BlueButton>
    

    如您所见,如果您尝试将组合的 React 组件与其他样式的组件一起包装(您必须继续传递className),则样式化组合的 React 组件可能会变得有点多余和冗长,所以我建议使用 @987654321 @方法。

    简而言之,将 styled-components 保持为styled.HTMLElement,如果需要对其进行包装,则使用上面提到的 compose(指其他组件)方法:

    import styled from "styled-components";
    
    const Button = styled.button`
      color: red;
    `;
    
    const BlackBlueButton = styled.div`
      background: black;
    
      ${Button} {
        color: blue;
      }
    `;
    
    // In short, the result is that the "Button" below gets two classNames, one from 
    // itself (styled.button) and another from "BlackBlueButton".
    const Example = () => (
      <BlackBlueButton>
        <Button>Test</Button>
      </BlackBlueButton>
    );
    

    另外,如果您想创建灵活的组件,请查看answer

    【讨论】:

    • 谢谢,这有帮助。我试图寻找一种解决方案,使在按钮(例如主按钮)上设置指示器变得简单,并将其传递给按钮组件以确定特定样式。
    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多