css - 样式化的组件,两层 className - 如何在组件声明中应用样式?
问题描述
我在 next.js 中创建了一个带有组件样式的 Container 组件。当我在整个站点中声明使用此容器组件时,我想为其添加一个 className 并根据其使用的上下文对其进行主观样式设置。
这是我的 Container 组件的示例:
const Container = (props) => (
<>
<div className="container">
{props.children}
</div>
<style jsx>{`
.container{
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
`}</style>
</>
)
export default Container;
所以,我想给它1200px的最大宽度,并用自动边距居中。没问题,我已经做到了。
现在,我打算在我的网站标题中使用这个组件。但在标题的情况下,我希望 Container 组件是一个 flexbox:
import Container from './Container'
const Header = (props) => (
<>
<header>
<Container className="header-col">
<div>
<h1>{props.title}</h1>
</div>
<nav>
<ul>
{/* Navigation items */}
</ul>
</nav>
</Container>
</header>
<style jsx>{`
.header-col{
display: flex;
justify-content: space-between;
}
`}</style>
</>
)
export default Header;
当我查看该站点时,我注意到我在标题中为 Container 组件指定的 flexbox 样式不存在。
我期待 className 生效,并允许我添加其他样式。
我相信这与认为 className 不是类名,而是道具有关。但是,我想通过在组件上创建样式继承来保持我的代码干燥。
我怎么能这样做?
谢谢您的帮助!
解决方案
这是样式化组件的工作:
import React from "react";
import styled from "styled-components";
export default function App() {
return (
<>
<Container custom={"header"}>
<h1>Very fancy h1 with flex display</h1>
</Container>
<Container custom={"regular"}>
<h1>Non-fancy h1 with no flex display</h1>
</Container>
</>
);
}
const Container = styled.div`
display: ${(props) => (props.custom === "header" ? "flex" : "block")};
/* you can call your prop ^^^^^^ whatever you want,
just change it on the container element too*/
& h1 {
/* you can apply css to children like so */
font-family: ${(props) =>
props.custom === "header"
? '"Courier New", Courier, monospace'
: '"Arial Black", Gadget, sans-serif'};
}
`;
在上面,我创建了一个自定义样式组件,它接收custom
道具,然后有条件地更改您要调整的值。为了使更改更直观,我还设置了字体样式,以便您可以看到两个<Container>
元素之间的直接区别。
对于更具可扩展性的解决方案(例如,对于不同的主题),请使用ThemeProvider
:
import React from "react";
import styled, { ThemeProvider } from "styled-components";
export default function App() {
return (
<>
<ThemeProvider theme={ContainerHeader}>
<Container>
<h1>Very fancy h1 with flex display</h1>
</Container>
</ThemeProvider>
<Container theme={"regular"}>
<h1>Non-fancy h1 with no flex display</h1>
</Container>
</>
);
}
const Container = styled.div`
display: ${(props) => props.theme.display};
& h1 {
font-family: ${(props) => props.theme.h1Font};
}
`;
Container.defaultProps = {
theme: {
display: "block",
h1Font: '"Arial Black", Gadget, sans-serif'
}
};
const ContainerHeader = {
display: "flex",
h1Font: '"Courier New", Courier, monospace'
};
CodeSandbox:https ://codesandbox.io/s/stack-conditional-styled-components-vmnpn?file=/src/App.js:0-773
推荐阅读
- java - Tomcat使用域名时找不到xxx.jsp
- laravel - Laravel 5.3 中刀片组件的使用
- rust - 为什么将值移动到闭包中仍然有错误消息“不能将不可变的局部变量借用为可变的”?
- spring - 如何在一个事务中保存两个相同类型的实体?
- javascript - 在猫头鹰旋转木马中设置旋转木马高度
- java - 在 Spring Security 中使用 UserDetails 实现登录不起作用
- r - 如何在绘图上写出均值、最小值、最大值、中值、P 值和安德森-达林测试结果的结果
- r - 在R中使用udpipe提取关键字时的for循环
- android - 为什么这个分页库示例的性能比仅仅一个回收器视图差得多?
- android - Lenovo Smart Display 或 Google Home Hub 上的 Android Things?