如何使用 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>
);
}
问题:
MobileHeader
和 DesktopHeader
分量:
我想这就是问题所在。我可以像在 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>
我正在尝试构建响应式 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>
);
}
问题:
MobileHeader
和 DesktopHeader
分量:
我想这就是问题所在。我可以像在 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>