Подтвердить что ты не робот

Рекомендации по эффективному стилю в React.js

Я знаю, что вы можете указать стили в классах React, например:

var MyDiv = React.createClass({
  render: function() {
    var style = {
      color: 'white',
      fontSize: 200
    };

    return <div style={style}> Have a good and productive day! </div>;
  }
});

Должен ли я стремиться делать все стили таким образом и не иметь стилей вообще, указанных в моем файле CSS?

Или я должен полностью избегать встроенных стилей?

Кажется странным и беспорядочным, чтобы немного поработать - два места нужно было бы проверить при настройке стиля.

4b9b3361

Ответ 1

Существует не так много "лучших практик". Те из нас, кто использует встроенные стили для компонентов React, все еще очень много экспериментируют.

Есть несколько подходов, которые сильно различаются: Реагируйте на диаграмму сравнения библиотек inline-style

Все или ничего?

То, что мы называем "стилем", на самом деле включает в себя довольно много концепций:

  • Макет - как элемент/компонент выглядит по отношению к другим
  • Внешний вид - характеристики элемента/компонента
  • Поведение и состояние - как элемент/компонент выглядит в данном состоянии

Начните с государственных стилей

React уже управляет состоянием ваших компонентов, что делает стили состояния и поведения естественными для согласования с логикой вашего компонента.

Вместо того чтобы создавать компоненты для рендеринга с помощью условных классов состояний, рассмотрите возможность непосредственного добавления стилей состояний:

// Typical component with state-classes
<li 
 className={classnames({ 'todo-list__item': true, 'is-complete': item.complete })} />


// Using inline-styles for state
<li className='todo-list__item'
 style={(item.complete) ? styles.complete : {}} />

Обратите внимание, что мы используем класс для оформления внешнего вида, но больше не используем какой-либо .is- префиксный класс для состояния и поведения.

Мы можем использовать Object.assign (ES6) или _.extend (подчеркивание /lodash), чтобы добавить поддержку нескольких состояний:

// Supporting multiple-states with inline-styles
<li 'todo-list__item'
 style={Object.assign({}, item.complete && styles.complete, item.due && styles.due )}>

Настройка и повторное использование

Теперь, когда мы используем Object.assign становится очень просто сделать наш компонент многократно используемым с разными стилями. Если мы хотим переопределить стили по умолчанию, мы можем сделать это на сайте вызова с помощью реквизита, например, так: <TodoItem dueStyle={ fontWeight: "bold" }/>. Реализовано так:

<li 'todo-list__item'
 style={Object.assign({},
         item.due && styles.due,
         item.due && this.props.dueStyles)}>

раскладка

Лично я не вижу веской причины для встроенных стилей макета. Существует множество отличных систем макетов CSS. Я бы просто использовал один.

Тем не менее, не добавляйте стили макета непосредственно в ваш компонент. Оберните ваши компоненты компонентами макета. Вот пример.

// This couples your component to the layout system
// It reduces the reusability of your component
<UserBadge
 className="col-xs-12 col-sm-6 col-md-8"
 firstName="Michael"
 lastName="Chan" />

// This is much easier to maintain and change
<div class="col-xs-12 col-sm-6 col-md-8">
  <UserBadge
   firstName="Michael"
   lastName="Chan" />
</div>

Для поддержки макета я часто пытаюсь проектировать компоненты, чтобы они были на 100% width и height.

Внешность

Это самая спорная область дебатов "в стиле". В конечном счете, это зависит от вашего проекта и комфорта вашей команды с JavaScript.

Одно можно сказать наверняка, вам понадобится помощь библиотеки. Состояния браузера (:hover :focus) и медиа-запросы болезненны в сыром React.

Мне нравится Radium, потому что синтаксис этих жестких частей разработан для моделирования синтаксиса SASS.

Код организации

Часто вы видите объект стиля вне модуля. Для компонента списка задач он может выглядеть примерно так:

var styles = {
  root: {
    display: "block"
  },
  item: {
    color: "black"

    complete: {
      textDecoration: "line-through"
    },

    due: {
      color: "red"
    }
  },
}

функции получения

Добавление логики стилей в ваш шаблон может стать немного грязным (как видно выше). Мне нравится создавать функции получения для вычисления стилей:

React.createClass({
  getStyles: function () {
    return Object.assign(
      {},
      item.props.complete && styles.complete,
      item.props.due && styles.due,
      item.props.due && this.props.dueStyles
    );
  },

  render: function () {
    return <li style={this.getStyles()}>{this.props.item}</li>
  }
});

Дальнейшее наблюдение

Я обсуждал все это более подробно в React Europe в начале этого года: встроенные стили и когда лучше всего "просто использовать CSS".

Я рад помочь, когда вы делаете новые открытия по пути :) Ударь меня → @chantastic

Ответ 2

Атрибут style в React ожидает, что значение будет объектом, то есть парой ключ-значение.

style = {} будет внутри другой объект, например {float:'right'} чтобы он работал.

<span style={{float:'right'}}>{'Download Audit'}</span>

Надеюсь, что это решает проблему

Ответ 3

Я использую встроенные стили в моих компонентах React. Я нахожу гораздо более ясным, чтобы группировать стили внутри компонентов, потому что всегда ясно, какие стили он делает и чего нет. Плюс, имея полную мощность Javascript под рукой, действительно упрощает более сложные требования к стилю.

Сначала я не был убежден, но после долгих месяцев работы над ним я полностью конвертировался и в процессе преобразования всех моих CSS в встроенные или другие JS-методы css.

Эта презентация сотрудника Facebook и вкладчика React Contributor "vjeux" также очень полезна - https://speakerdeck.com/vjeux/react-css-in-js

Ответ 4

Основная цель атрибута style - динамические, основанные на состоянии стили. Например, вы можете иметь стиль ширины на индикаторе выполнения на основе некоторого состояния или позиции или видимости на основе чего-то еще.

Стили в JS налагают ограничение, которое приложение не может предоставить настраиваемому стилю для повторно используемого компонента. Это вполне приемлемо в вышеупомянутых ситуациях, но не при изменении видимых характеристик, особенно в цвете.

Ответ 5

Джеймс К. Нельсон в своем письме "Почему вы не должны реагировать на компоненты с помощью JavaScript" утверждает, что на самом деле нет необходимости использовать встроенные стили со своими минусами. Его утверждение состоит в том, что старое скучное css с меньшим /scss - лучшее решение. Часть его тезисов в пользу css:

  • расширяемый внешний вид
  • с возможностью использования (встроенные стили перекрывают все)
  • дизайнер дружественный

Ответ 6

Что я делаю - это предоставить каждому из моих многократно используемых компонентов уникальное имя пользовательского элемента, а затем создать файл css для этого компонента, в частности, со всеми параметрами стиля для этого компонента (и только для этого компонента).

var MyDiv = React.createClass({
  render: function() {
    return <custom-component style={style}> Have a good and productive day! </custom-component>;
  }
});

И в файле "custom-component.css" каждая запись начнется с тега пользовательского компонента:

custom-component { 
   display: block; /* have it work as a div */
   color: 'white'; 
   fontSize: 200; 
} 
custom-component h1 { 
  font-size: 1.4em; 
}

Это означает, что вы не теряете критического понятия разделения беспокойства. Просмотр и стиль. Если вы делитесь своим компонентом, другим пользователям легче сопоставить их с остальной частью своей веб-страницы.

Ответ 7

Стилизация в JSX очень похожа на стилизацию в HTML.

HTML Case:

div style = "background-color: red; color: white"

Дело JSX:

div style = {{backgroundColor: 'red', color: 'white'}}

Ответ 8

Это действительно зависит от того, насколько велико ваше приложение, хотите ли вы использовать упаковщики, такие как веб- пакет и объединять CSS и JS вместе в сборке, и то, как вы хотите управлять потоком приложений! В конце дня, в зависимости от вашей ситуации, вы можете принять решение!

Я предпочитаю организовывать файлы в больших проектах, разделяя файлы CSS и JS, проще делиться, людям с интерфейсом проще просто просматривать CSS файлы, а также гораздо более аккуратную организацию файлов для всего приложения!

Всегда думайте так, убедитесь, что на этапе разработки все находится там, где они должны быть, правильно названы и другим разработчикам будет легко найти вещи...

Я лично смешиваю их, в зависимости от моих потребностей, например... Попробуйте использовать внешний CSS, но если необходимо, React также примет стиль, вам нужно передать его как объект со значением ключа, что-то вроде этого ниже:

import React from 'react';

const App = props => {
  return (
    <div className="app" style={{background: 'red', color: 'white'}}>  /*<<<<look at style here*/
      Hello World...
    </div>
  )
}

export default App;

Ответ 9

Обычно у меня есть файл scss, связанный с каждым компонентом React. Но я не вижу причин, почему вы не инкапсулируете компонент логикой и не смотрите в нее. Я имею в виду, что у вас есть аналогичная вещь с веб-компонентами.

Ответ 10

Вы можете использовать react-theme, чтобы организовать свои встроенные стили и сделать их легко настраиваемыми, когда вы создаете повторно используемый компонент.

Он работает аналогично ThemeManager в материале-ui.

Ответ 11

В зависимости от вашей конфигурации встроенный стиль может предложить вам горячую перезагрузку. Веб-страница сразу же отображается повторно при каждом изменении стиля. Это помогает мне быстрее разрабатывать компоненты. Сказав это, я уверен, что вы можете настроить горячую перезагрузку для CSS + SCSS.

Ответ 12

Для некоторых компонентов проще использовать встроенные стили. Кроме того, мне проще и лаконичнее (поскольку я использую Javascript, а не CSS) анимировать стили компонентов.

Для автономных компонентов я использую "Оператор распространения" или "...". Для меня это понятно, красиво и работает в стесненных условиях. Вот небольшая анимация загрузки, которую я сделал, чтобы показать ее преимущества:

<div style={{...this.styles.container, ...this.state.opacity}}>
    <div style={{...this.state.colors[0], ...this.styles.block}}/>
    <div style={{...this.state.colors[1], ...this.styles.block}}/>
    <div style={{...this.state.colors[2], ...this.styles.block}}/>
    <div style={{...this.state.colors[7], ...this.styles.block}}/>
    <div style={{...this.styles.block}}/>
    <div style={{...this.state.colors[3], ...this.styles.block}}/>
    <div style={{...this.state.colors[6], ...this.styles.block}}/>
    <div style={{...this.state.colors[5], ...this.styles.block}}/>
    <div style={{...this.state.colors[4], ...this.styles.block}}/>
  </div>

    this.styles = {
  container: {
    'display': 'flex',
    'flexDirection': 'row',
    'justifyContent': 'center',
    'alignItems': 'center',
    'flexWrap': 'wrap',
    'width': 21,
    'height': 21,
    'borderRadius': '50%'
  },
  block: {
    'width': 7,
    'height': 7,
    'borderRadius': '50%',
  }
}
this.state = {
  colors: [
    { backgroundColor: 'red'},
    { backgroundColor: 'blue'},
    { backgroundColor: 'yellow'},
    { backgroundColor: 'green'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
    { backgroundColor: 'white'},
  ],
  opacity: {
    'opacity': 0
  }
}

Затем в componentWillMount() я устанавливаю интервал примерно так...

this.interval = setInterval(() => {
  let colors = this.state.colors;
  let opacity = this.state.opacity;

  if(this.props.reverse) {
    let color = colors[colors.length-1];
    colors.pop();
    colors.unshift(color)
  } else {
    let color = colors[0];
    colors.shift();
    colors.push(color);
  }

  opacity['opacity'] < 1 ? opacity['opacity']+=0.06 : null;

  this.setState({colors, opacity});
}, this.speed);

Ответ 13

Вы можете использовать встроенные стили, но у вас будут некоторые ограничения, если вы будете использовать их во всех своих стилях, некоторые известные ограничения: вы не можете использовать псевдо-селекторы CSS и медиа-запросы в есть.

Вы можете использовать Radium , чтобы решить эту проблему, но, тем не менее, я чувствую, что проект будет расти и станет громоздким.

Я бы порекомендовал использовать CSS-модули.

используя CSS-модули, у вас будет свобода писать CSS в CSS файле, и вам не придется беспокоиться о конфликтах имен, об этом позаботятся CSS-модули.

Преимущество этого метода в том, что он предоставляет вам функциональность стилей для конкретного компонента. Это создаст гораздо более понятный код и читаемую архитектуру проекта для следующего разработчика, который будет работать над вашим проектом.

Ответ 14

Вот логическое моделирование в синтаксисе JSX:

style={{display: this.state.isShowing ? "inherit" : "none"}}

Ответ 15

Проблема со встроенными стилями - это политики безопасности контента (CSP), которые становятся все более распространенными, что не позволяет. Поэтому я рекомендую полностью исключить встроенные стили.

Update: Чтобы объяснить далее, CSP представляют собой HTTP-заголовки, отправленные сервером, которые ограничивают, какой контент может отображаться на странице. Это просто дальнейшее смягчение, которое может быть применено к серверу, чтобы остановить злоумышленника от совершения чего-либо непослушного, если разработчик плохо кодирует сайт.

Цель большинства этих ограничений - остановить атаки XSS (межсайтовый скриптинг). XSS - это то, где злоумышленник определяет способ включить свой собственный javascript на вашу страницу (например, если я сделаю свое имя пользователя bob<SCRIPT>alert("hello")</SCRIPT>, а затем опубликую комментарий, и вы заходите на страницу, он не должен показывать предупреждение). Разработчики должны отрицать возможность добавления пользователем такого контента на сайт, но на случай, если они допустили ошибку, CSP блокирует загрузку страницы, если она найдет теги script>.

CSP - это всего лишь дополнительный уровень защиты для разработчиков, чтобы убедиться, что они допустили ошибку, что злоумышленник не может создавать проблемы для посетителей этого сайта.

Итак, все это XSS, но что, если злоумышленник не может включать теги <script>, но может включать теги <style> или включать параметр style= в тег? Затем он сможет изменить внешний вид сайта таким образом, чтобы вы обманом нажали на неправильную кнопку или какую-то другую проблему. Это гораздо меньше беспокоит, но все равно что-то избежать, и CSP делает это для вас.

Хорошим ресурсом для тестирования сайта для CSP является https://securityheaders.io/

Вы можете узнать больше о CSP: http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Ответ 16

Вы также можете использовать StrCSS, он создает изолированные имена классов и многое другое! Пример кода будет выглядеть так. Вы можете (необязательно) установить расширение VSCode из Visual Studio Marketplace для поддержки подсветки синтаксиса!

источник: strcss

import { Sheet } from "strcss";
import React, { Component } from "react";

const sheet = new Sheet('
  map button
    color green
    color red !ios
    fontSize 16
  on hover
    opacity .5
  at mobile
    fontSize 10
');

export class User extends Component {
  render() {
    return <div className={sheet.map.button}>
      {"Look mom, I'm green!
      Unless you're on iOS..."}
    </div>;
  }
}

Ответ 17

По сравнению с записью ваших стилей в CSS файле атрибут стиля React имеет следующие преимущества:

  1. Возможность использовать инструменты javascript в качестве языка программирования обеспечивает контроль стиля ваших элементов. Это включает в себя встраивание переменных, использование условий и передачу стилей дочернему компоненту.
  2. "Компонентный" подход. Больше не нужно разделять HTML, JS и CSS код, написанный для компонента. Код компонента объединен и записан в одном месте.

Тем не менее, атрибут стиля React имеет несколько недостатков - вы не можете

  1. Не могу использовать медиа-запросы
  2. Не могу использовать псевдо-селекторы,
  3. менее эффективен по сравнению с CSS-классами.

Используя CSS в JS, вы можете получить все преимущества тега стиля без этих недостатков. На сегодняшний день существует несколько популярных хорошо поддерживаемых css в js-библиотеках, в том числе: Emotion, Styled-Components и Radium. Эти библиотеки предназначены для CSS, как React для HTML. Они позволяют вам писать свой CSS и контролировать свой CSS в своем коде JS.

давайте сравним, как будет выглядеть наш код для стилизации простого элемента. Мы создадим div "hello world", чтобы он показывался большим на рабочем столе и меньше на мобильном.

Использование атрибута стиля

return (
   <div style={{fontSize:24}} className="hello-world">
      Hello world
   </div>
)

Так как медиа-запрос невозможен в теге стиля, нам нужно добавить className к элементу и добавить правило css.

@media screen and (max-width: 700px){
   .hello-world {
      font-size: 16px; 
   }
}

Использование Emotion 10 css tag

return (
   <div
      css={{
         fontSize: 24, 
         [CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY]:{
            fontSize: 16 
         }
      }
   >
      Hello world
   </div>
)

Emotion также поддерживает строки шаблонов и стилизованные компоненты. Поэтому, если вы предпочитаете, вы можете написать:

return (
   <Box>
      Hello world
   </Box>
)

const Box = styled.div'
   font-size: 24px; 
   ${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
      font-size: 16px; 
   }
'

За капюшонами "Css in JS" используются классы css. Эмоция была специально разработана с учетом производительности и использует кеширование. По сравнению с атрибутами стиля React Css в JS обеспечит лучшую производительность.

Лучшие практики

Вот несколько рекомендаций, которые я рекомендую:

  1. Если вы хотите стилизовать свои элементы встроенным образом или в JS, используйте библиотеку css-in-js, не используйте атрибут style.

Должен ли я стремиться делать все стили таким образом, и в моем CSS файле вообще не указаны стили?

  1. Если вы используете решение css-in-js, нет необходимости писать стили в файлах Css. Написание вашего CSS в JS лучше, так как вы можете использовать все инструменты языка программирования, которые предоставляет JS.

я должен полностью избегать встроенных стилей?

  1. Структурирование вашего кода стиля в JS очень похоже на структурирование вашего кода в целом. Например:
    • распознайте повторяющиеся стили и запишите их в одном месте. Есть два способа сделать это в Emotion:
// option 1 - Write common styles in CONSTANT variables
// styles.js
export const COMMON_STYLES = {
   BUTTON: css'
      background-color: blue; 
      color: white; 
      :hover {
         background-color: dark-blue; 
      }
   '
}

// SomeButton.js
const SomeButton = (props) => {
   ...
   return (
      <button
         css={COMMON_STYLES.BUTTON}
         ...
      >
         Click Me
      </button>
   )
}

// Option 2 - Write your common styles in a dedicated component 

const Button = styled.button'
   background-color: blue; 
   color: white; 
   :hover {
      background-color: dark-blue; 
   }   
'

const SomeButton = (props) => {
   ...
   return (
      <Button ...> 
         Click me
      </Button>
   )
}

  • Шаблон кодирования React состоит из инкапсулированных компонентов - HTML и JS, управляющий компонентом, записываются в одном файле. Вот где находится ваш код CSS/style для стилизации этого компонента.

  • При необходимости добавьте в свой компонент стайлинг. Таким образом, вы можете повторно использовать код и стиль, написанный в дочернем компоненте, и настраивать его в соответствии с вашими конкретными потребностями родительским компонентом.

const Button = styled.button([COMMON_STYLES.BUTTON, props=>props.stl])

const SmallButton = (props)=>(
   <Button 
      ...
      stl={css'font-size: 12px'}
   >
      Click me if you can see me
   </Button>
)

const BigButton = (props) => (
   <Button
      ...
      stl={css'font-size: 30px;'}
   >
      Click me
   </Button>
)

Ответ 18

Некоторое время нам требуется стилизовать какой-то элемент из компонента, но если нам нужно отобразить только этот компонент или его стиль меньше, чем вместо использования класса CSS, мы используем встроенный стиль в реагировать на js. Встроенный стиль responsejs такой же, как и встроенный стиль HTML, только имена свойств немного отличаются

Напишите свой стиль в любом теге, используя style = {{prop: "value"}}

import React, { Component } from "react";
    import { Redirect } from "react-router";

    class InlineStyle extends Component {
      constructor(props) {
        super(props);
        this.state = {};
      }

      render() {
        return (
          <div>
            <div>
              <div
                style={{
                  color: "red",
                  fontSize: 40,
                  background: "green"
                }}// this is inline style in reactjs
              >

              </div>
            </div>
          </div>
        );
      }
    }
    export default InlineStyle;