在样式化组件中扩展样式时,有没有办法传递道具?

时间:2019-02-20 19:14:13

标签: reactjs styled-components

使用样式化的组件扩展基本组件时,是否可以从扩展组件中的基本组件访问道具?

这是基础组件及其样式组件。在第8行,我传入isOpen。在样式化的组件中,我在两种背景颜色之间切换,它们基于isOpen

const StyledBaseComponent = styled.button`
  background-color: ${({ isOpen }) => (isOpen ? 'cyan' : 'orange')};
`
function BaseComponent(props) {
  const [isOpen, toggleOpen] = useState(false)

  return (
    <StyledBaseComponent {...props} isOpen={isOpen} onClick={() => toggleOpen(!isOpen)}>
      isOpen - {String(isOpen)}
    </StyledBaseComponent>
  )
}

这是扩展组件及其样式组件。在第2行中,我尝试使用父级的isOpen来切换颜色,但是它是未定义的,因此颜色将始终为yellow

const StyledExtendedComponent = styled(BaseComponent)`
  background-color: ${({ isOpen }) => (isOpen ? 'pink' : 'yellow')};
`
function ExtendedComponent() {
  return <StyledExtendedComponent />
}

以下是此问题的代码框:https://codesandbox.io/s/4q60qqx027。左按钮是基本组件,按预期方式工作。扩展基本组件的右键不会改变颜色。

1 个答案:

答案 0 :(得分:0)

一种解决方案可以包括className道具,请参见官方文档:styling-any-components。我无法打开您的链接以查看是否可行。

第二种解决方法是将颜色作为道具传递到BaseComponent中,并使用BaseComponent需要的默认颜色:

const { openColor = "cyan", closedColor = "orange" } = this.props;

return (
  <StyledBaseComponent
    isOpen={isOpen}
    onClick={() => this.toggleOpen()}
    openColor={openColor}
    closedColor={closedColor}
  >
    isOpen - {String(isOpen)}
  </StyledBaseComponent>
)

所以之后,在ExtendedComponent

export function ExtendedComponent() {
  return <BaseComponent openColor="pink" closedColor="yellow" />;
}

示例here

另一种可能的解决方案是将样式化的组件作为prop传递给BaseComponent。 像这样:

const StyledBaseComponent = styled.button`
  background-color: ${({ isOpen }) => (isOpen ? "cyan" : "orange")};
`;

const StyledExtendedComponent = styled(StyledBaseComponent)`
  background-color: ${({ isOpen }) => (isOpen ? "pink" : "yellow")};
`;

function App() {
  return (
    <div className="App">
      <BaseComponent MyButtom={StyledBaseComponent} />
      <BaseComponent MyButtom={StyledExtendedComponent} />
    </div>
  );
}

BaseComponent

  render() {
    const { isOpen } = this.state;
    const { MyButtom } = this.props;

    return (
      <MyButtom isOpen={isOpen} onClick={() => this.toggleOpen()}>
        isOpen - {String(isOpen)}
      </MyButtom>
    );
  }

查看示例here。您可以使用钩子来实现相同的目的。