样式化组件中的条件渲染
Posted
技术标签:
【中文标题】样式化组件中的条件渲染【英文标题】:conditional rendering in styled components 【发布时间】:2018-07-08 05:31:48 【问题描述】:如何在样式组件中使用条件渲染来使用 React 中的样式组件将我的按钮类设置为活动?
在 css 中我会这样做:
<button className=this.state.active && 'active'
onClick= () => this.setState(active: !this.state.active) >Click me</button>
在样式化的组件中,如果我尝试在类名中使用“&&”,它不喜欢它。
import React from 'react'
import styled from 'styled-components'
const Tab = styled.button`
width: 100%;
outline: 0;
border: 0;
height: 100%;
justify-content: center;
align-items: center;
line-height: 0.2;
`
export default class Hello extends React.Component
constructor()
super()
this.state =
active: false
this.handleButton = this.handleButton.bind(this)
handleButton()
this.setState( active: true )
render()
return(
<div>
<Tab onClick=this.handleButton></Tab>
</div>
)
【问题讨论】:
【参考方案1】:通过有条件地应用它们,似乎也可以使用类名:
const BoxClassname = styled.div.attrs((props) => (
className: clsx(props.$primary && "primary")
))`
background: #000;
height: 1px;
width: 50px;
&.primary
background: pink;
`;
/*
// You could also use a second component instead of .attrs
export const BoxClassname = (props) =>
return (
<BoxClassnameWrapper
className=clsx(props.$primary && "primary")
...props
/>
);
;
*/
我喜欢这种语法的一点是不要过多地混合 JS 和 CSS。
限制是它看起来更慢,请参阅this demo code sandbox 以获得性能比较。我真的不明白为什么:/因为逻辑上。
我在阅读Josh Comeau take on using CSS variables in Styled Components后产生了这个想法。
CSS 变量让您配置...变量(切换颜色等) 从逻辑上讲,classNames
+ CSS 选择器让您定义条件
毕竟,这个逻辑已经存在于 CSS 中,className 已经是用来处理条件渲染的了。 Styled Components 有助于保持样式干净隔离并处理高级场景,但我不喜欢它过多地干预样式。
【讨论】:
【参考方案2】:我还没有见过这种语法,我觉得当你需要使一个完整的块条件时最干净:
const StyledButton = styled(button)`
display: flex;
background-color: white;
$props => !props.disabled
&:hover
background-color: red;
&:active
background-color: blue;
`;
因此无需关闭/打开刻度即可使其正常工作。
【讨论】:
我喜欢这种语法,但你确定它适用于非布尔检查吗? (例如 props => props.foo === "bar")似乎对我检查特定值不起作用 它的工作原理是因为我经常使用这种语法。您可能需要在其中放置一个 console.log 以检查“foo”是否已实际定义。 您能详细说明一下吗?我不明白它为什么起作用,这是否特定于样式化组件的工作原理? 是的,我确认 TS 在我尝试执行以下操作时会抱怨:$(props) => props.$isSelected ...
【参考方案3】:
在您的示例中我没有注意到任何 &&,但是对于样式组件中的条件渲染,您可以执行以下操作:
// Props are component props that are passed using <StyledYourComponent prop1="A" prop2="B"> etc
const StyledYourComponent = styled(YourComponent)`
background: $props => props.active ? 'darkred' : 'limegreen'
`
在上面的例子中,当 StyledYourComponent 使用 active 属性渲染时背景会变暗,如果没有提供 active 属性或者它是假的 Styled-components 会自动为你生成类名:)
如果要添加多个样式属性,则必须使用从 styled-components 导入的 css 标签:
在您的示例中我没有注意到任何 &&,但是对于样式组件中的条件渲染,您可以执行以下操作:
import styled, css from 'styled-components'
// Props are component props that are passed using <StyledYourComponent prop1="A" prop2="B"> etc
const StyledYourComponent = styled(YourComponent)`
$props => props.active && css`
background: darkred;
border: 1px solid limegreen;`
`
或者您也可以使用 object 来传递样式,但请记住 CSS 属性应该是驼峰式:
import styled from 'styled-components'
// Props are component props that are passed using <StyledYourComponent prop1="A" prop2="B"> etc
const StyledYourComponent = styled(YourComponent)`
$props => props.active && (
background: 'darkred',
border: '1px solid limegreen',
borderRadius: '25px'
)
`
【讨论】:
css
- ??。我不知道那件事。它在文档中的什么位置?
@CodeFinity 它在那里:styled-components.com/docs/api#css【参考方案4】:
这是一个使用 TypeScript 的简单示例:
import * as React from 'react';
import FunctionComponent from 'react';
import styled, css from 'styled-components';
interface IProps
isProcessing?: boolean;
isDisabled?: boolean;
onClick?: () => void;
const StyledButton = styled.button<IProps>`
width: 10rem;
height: 4rem;
cursor: pointer;
color: rgb(255, 255, 255);
background-color: rgb(0, 0, 0);
&:hover
background-color: rgba(0, 0, 0, 0.75);
$( disabled ) =>
disabled &&
css`
opacity: 0.5;
cursor: not-allowed;
`
$( isProcessing ) =>
isProcessing &&
css`
opacity: 0.5;
cursor: progress;
`
`;
export const Button: FunctionComponent<IProps> = (
children,
onClick,
isProcessing,
) =>
return (
<StyledButton
type="button"
onClick=onClick
disabled=isDisabled
isProcessing=isProcessing
>
!isProcessing ? children : <Spinner />
</StyledButton>
);
;
<Button isProcessing=this.state.isProcessing onClick=this.handleClick>Save</Button>
【讨论】:
【参考方案5】:如果你的状态是这样在你的类组件中定义的:
class Card extends Component
state =
toggled: false
;
render()
return(
<CardStyles toggled=this.state.toggled>
<small>I'm black text</small>
<p>I will be rendered green</p>
</CardStyles>
)
使用基于该状态的三元运算符定义样式组件
const CardStyles = styled.div`
p
color: $props => (props.toggled ? "red" : "green");
`
它应该将这里的 <p>
标记呈现为绿色。
这是一种非常时髦的造型方式
【讨论】:
【参考方案6】:你可以这样做
<Tab active=this.state.active onClick=this.handleButton></Tab>
在你的风格中是这样的:
const Tab = styled.button`
width: 100%;
outline: 0;
border: 0;
height: 100%;
justify-content: center;
align-items: center;
line-height: 0.2;
$( active ) => active && `
background: blue;
`
`;
【讨论】:
文档:Adapting based on props. 在 TypeScript 中,您需要使用( active : any)
或 withProps。
它在 CSS 字符串中添加了一个false
会导致麻烦
@LucasWillems 如果您使用过时的 babel 转译器并做出反应。 React 不再呈现虚假值
条件代码不应包含在普通的反引号中,而应包含在css``
以上是关于样式化组件中的条件渲染的主要内容,如果未能解决你的问题,请参考以下文章
样式化组件 + 故事书:当我传递新样式时,SVG 图标不会重新渲染
如何将样式化组件作为属性添加到 TypeScript 中的另一个样式化组件?
ReactReact全家桶组件+组件三大核心属性state-props-refs+事件处理与条件渲染+列表与表单+状态提升与组合+高阶函数与函数+函数柯里化
ReactReact全家桶组件+组件三大核心属性state-props-refs+事件处理与条件渲染+列表与表单+状态提升与组合+高阶函数与函数+函数柯里化