如何使用 styled-components 设计我自己的组件(响应式 header)?

How to style my own components (responsive header) with styled-components?

我正在尝试构建响应式 header 组件。它应该在桌面上使用 display:inline-block 显示所有导航链接,在移动设备上它应该使用 display:block 显示所有导航链接。

注意:我正在使用 react-responsive 进行媒体查询,所以:

import Responsive from 'react-responsive';

function Mobile(props) {
  return(<Responsive {...props} maxWidth={800}/>);
}

function Desktop(props) {
  return(<Responsive {...props} minWidth={801}/>);
}

<Mobile> 将在移动设备上呈现,<Desktop> 将在桌面设备上呈现。那部分工作正常。我只是无法相应地更改样式。

请注意,下面的所有代码都在 Header.js.

我目前的方法如下:

Header分量

是我的其余代码导出和使用的那个。它在移动设备上呈现 <MobileHeader>,在桌面设备上呈现 <DesktopHeader>。两者都是样式组件。

function Header(props) {
  return(
    <React.Fragment>
      <Mobile>
        <MobileHeader
          authUser={props.authUser}
        />
      </Mobile>
      <Desktop>
        <DesktopHeader
          authUser={props.authUser}
        />
      </Desktop>
  </React.Fragment>
  );
}

HeaderBase分量:

我设计的 <MobileHeader><DesktopHeader> 都应该设计 HeaderBase 组件的样式,如下(简化):

function HeaderBase(props) {
  return(
    <header>
    <div>

      <h1>Header</h1>
      <ul>
        <li>
          <Link to={ROUTES.HOME}>Home</Link>
        </li>
        <li>
          <Link to={ROUTES.ACCOUNT}>Account</Link>
        </li>
      </ul>

    </div>
  </header>
  );
}

问题:

MobileHeaderDesktopHeader 分量:

我想这就是问题所在。我可以像在 li 中那样在样式化的自定义组件中引用 html 标签吗?因为这似乎行不通。不过,当我为常规 html 标签设置样式时,这会起作用。

你们推荐另一种方法吗?我的最终目标是拥有一个覆盖式侧边导航栏,当用户使用移动设备时,它会在您点击时从左侧出现。在桌面上,我会有一个常规的 inline-block 导航栏。由于每种情况下的链接都是相同的,我想我应该重用 HeaderBase 并使用 styled-components 相应地设计它的样式。

const MobileHeader = styled(HeaderBase)`
  li {
    display: block;
  }
`;

const DesktopHeader = styled(HeaderBase)`
  li {
    display: inline-block;
    padding: 5px;
    margin: 0;
    box-sizing: border-box;
  }
`;

刚刚发现问题所在:

根据 styled-components docs:

If you use the styled(MyComponent) notation and MyComponent does not render the passed-in className prop, then no styles will be applied. To avoid this issue, make sure your component attaches the passed-in className to a DOM node:

所以我需要一个由我的组件呈现的 "parent" html 节点来接收带有样式组件样式的 className 道具:

function HeaderBase(props) {
  return(
    <header>
    <div className={props.className}>  // <----- NOW IT WORKS!

      <h1>Header</h1>
      <Mobile>☰ I am mobile header</Mobile>
      <ul>
        <li>
          <Link to={ROUTES.HOME}>Home</Link>
        </li>