##Избавляемся от презентационных классов
###CSS: with modules & nesting(PostCSS/Sass/Less/Stylus)
Как происходит сейчас. Обычно мы используем презентационные классы. Популярная, но не лучшая практика.
Довольно частый кейс - добавить какое-то состояние компоненту. Мы в css создаем класс-модификатор is-active
.
style.css
.action {
border: 1px solid;
color: black;
background-color: black;
&.is-active {
color: red;
background-color: red;
}
}
Some React component
А в компоненте, согласно стейту, добавляем этот класс элемену. Примерно так:
component.js
import styles from './styles.css';
class ActionButton extends Component {
constructor() {
super();
this.state = {
active: true
}
}
render() {
const {active} = this.state;
return <a className={`action ${active && styles.isActive}`} onClick={this.props.action}>Action!</a>
}
}
###Css in JS: <Any>
+ css-tag
Some React component:
Используя трансформер и css in js мы можем создать функцию, которая принимает на вход объект состояния(context). И используя js expressions определять стили, не используя класс-модификатор. Примерно такая идея у styled-components. Всё, дополнительный класс нам не нужен.
component.js
import css from 'css/react'
const actionButton = css`
border: 1px solid;
color: ${data => data.active ? 'red' : 'black'};
background-color: ${data => data.active ? 'red' : 'black'};
`;
class ActionButton extends Component {
constructor() {
super();
this.state = {
active: true
}
}
render() {
return <a className={actionButton(this.state)} onClick={this.props.action}>Action!</a>
}
}
###Css in JS: <Any>
+ css-tag + theming
Пойдем дальше, благодаря очень простому апи, можно лкгко расширять цсс аттрибуты, юзать минксины, темы, полифилить!!!ваще всё. И не на каком-то диком синтаксисе как less/sass/stylus, а на обычном js. Вот этого уже никак не сможет PostCSS. Всего лишь нужно добавить в словарь(считай синглтон) функцию, имя которой будет левой частью css-декларации, а принимать в аргументы она будет правую часть. И вернет функцию, которой уже передаешь контекст. Изи? При этом, функция может вернуть сколько угодно полей(добавить префиксы, что угодно) или не вернуть :) Пример
Some React component:
component.js
import css from 'css/react'
// In global theme file
// Одна функция задает сразу цвет и цвет фона
css.addRule('active-color', color => data => data.active && {color, backgroundColor: color});
const actionButton = css`
border: 1px solid;
color: black;
background-color: black;
active-color: red;
`;
class ActionButton extends Component {
constructor() {
super();
this.state = {
active: true
}
}
render() {
return <a className={actionButton(this.state)} onClick={this.props.action}>Action!</a>
}
}
###Css in JS: <Any>
+ css-tag + theming & loader
Ну и на последок, стили можно вынести в цсс-подобный файл. И получается совсем красиво
style.css
.action-button {
border: 1px solid;
color: black;
background-color: black;
active-color: red;
}
Some React component:
component.js
import css from 'css/react'
import styles from './styles.css';
// In global theme file
css.addRule('active-color', color => data => data.active && {color, backgroundColor: color});
class ActionButton extends Component {
constructor() {
super();
this.state = {
active: true
}
}
render() {
const {actionButton} = styles(this.state);
return <a className={actionButton} onClick={this.props.action}>Action!</a>
}
}