样式化组件中的条件呈现

如何使用样式化组件中的条件呈现来使用 React 中的样式化组件将按钮类设置为活动的?

In css I would do it similarly to this:

<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>
)
}}
155329 次浏览

你可以简单地这样做

<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;
`}
`;

在你的例子中我没有注意到任何 & & ,但是对于样式化组件的条件渲染,你可以这样做:

// 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 呈现活动道具和石灰绿时,如果没有提供活动道具或者它是假的,背景将变暗 样式化组件自动为您生成类名:)

如果要添加多个样式属性,必须使用 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;`
}
`

或者你也可以使用对象来传递样式,但是要记住 CSS 属性应该是 camelCased:

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'
})
`

如果您的状态在类组件中定义如下:

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>标记渲染为绿色。

这是一种非常无礼的造型方式

下面是 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>

我还没有见过这样的语法,当你需要创建一个完整的块条件时,我觉得它是最干净的:

const StyledButton = styled(button)`
display: flex;
background-color: white;


${props => !props.disabled} {
&:hover {
background-color: red;
}


&:active {
background-color: blue;
}
}
`;

所以没有必要关闭/打开滴答声让它工作。

通过有条件地应用 classNames,似乎也可以使用 classNames:

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 在样式化组件中使用 CSS 变量之后有了这个想法。

  • CSS 变量允许您配置... 变量(切换颜色等)
  • 逻辑上,classNames + CSS 选择器让您定义条件

毕竟,这种逻辑已经存在于 CSS 中,className 已经用于处理条件呈现。样式化组件有助于保持样式的清晰隔离和处理高级场景,但我不喜欢它干涉太多的样式。