Skip to content

Instantly share code, notes, and snippets.

@blia
Last active February 24, 2017 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blia/2d4b9b3192294a5bb0474c9ae8efdb26 to your computer and use it in GitHub Desktop.
Save blia/2d4b9b3192294a5bb0474c9ae8efdb26 to your computer and use it in GitHub Desktop.

##Избавляемся от презентационных классов

###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>
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment