Не работают стили react

Самые распространенные ошибки в вашем React коде, которые вы (возможно) делаете

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

Весь код написан в ES6 стиле, поэтому, что бы повторить его вам нужно использовать Babel в вашем проекте (а еще есть такие кто его не использует?).

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

Если вам интересно, то добро пожаловать под кат.

В скобках перед каждым параграфом я оставил ссылку на eslint правило. Вы сможете позднее найти их в git и добавить в свой проект.

(react/forbid-component-props)

Первая распространенная ошибка это передача ‘style’ и ‘className’ как props в ваш компонент. Избегайте этого, так как вы добавите много сложности в ваши компоненты.

Вместо это можно использовать библиотеку ‘classnames’ и добавить интересные вариации в ваш компонент (если вы используете css классы):

(react/forbid-prop-types)

Следующая ошибка — не информативные propTypes. Не используйте PropTypes.any, PropTypes.array и PropTypes.object. Описывайте ваши props как можно подробнее. Это позволит вам оставить хорошую документацию на будущее, и вы (или другой разработчик) еще не раз скажите себе большое спасибо.

(react/forbid-foreign-prop-types)

Давайте продолжим с propTypes. Не используйте propTypes другого компонента:

Создайте файл в котором вы будете содержать в порядки ваши глобальные propTypes:

Это поможет babel-plugin-transform-react-remove-prop-types убрать propTypes из продакшен кода и сделать ваше приложение чуточку легче.

(react/no-access-state-in-setstate)

Следующая ошибка очень интересная:

Потому что setState это асинхронная функция состояния state в обоих случаях будет одинаковым.
this.state.counter будет равен 1 и мы получим:

Для того, что бы это избежать можно использовать setState callback который получает как аргумент прошлое состояние state:

(react/no-array-index-key)

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

React использует prop key как ссылку к DOM элементу, и это помогает ему быстро найти и отрендерить нужный компонент (все, конечно, сложнее, но я упростил специально).
Что случиться если вы добавите нового юзера в середину массива? React будет вынужден перерендерить все UserComponents после добавленного нового, так как индекс будет изменен для большого кол-ва компонентов. Используйте уникальные ключи вместо этого. Очень простой выход это id, которые вы получаете из вашей базы данных:

(react/no-did-mount-set-state), (react/no-did-update-set-state)

Эта ошибка так же очень часто встречается в моей практике. Если вы попытаетесь обновить state в componentDidUpdate методе, вы получите бесконечный цикл ре-рендера. React начинает проверку на ре-рендер когда у компонента меняется state или props. Если вы поменяете state после того как компонент замаунтился в DOM или уже обновился, вы запустите проверку заново и заново и заново…
При обновлении стейта в componentDidMount вы можете вызвать ре-рендер компонента еще один раз, так как функция вызывается один раз после маунтинга компонента в DOM.
Если у вас возникает необходимость обновлять данные именно после маунтинга компонента, я предлагаю использовать переменные класса:

(react/no-direct-mutation-state)

Мутация state это очень большая ошибка. Неконтролируемая мутация state приведет к необнаруживаемым багам и, как следствие, к большим проблемам. Мое персональное мнение это использование immutable-js, как библиотеку, которая добавляет иммутабельные структуры. И их вы можете использовать с Redux/MobX/Любой библиотекой state менеджмента. Так же вы можете использовать deepClone из lodash для клонирования state и последующей мутации клона или использовать новую фичу JS — деструкцию (destructuring):

(react/prefer-stateless-function)

Данное правило описывает больше улучшение вашего кода и приложения, чем ошибку, но я, все же, рекомендую следовать этому правилу. Если ваш компонент не использует state, сделайте его stateless компонентом (мне больше нравиться термин ‘pure component’):

(react/prop-types)

Пожалуйста, всегда добавляйте проверку на типы props (propTypes) если ваш компонент получает props. Думайте об этом как о документировании вашего кода. Вы еще не раз скажете себе ‘спасибо’ за это (а может быть и мне :)). PropTypes поможет вам понять и разобраться, что ваш компонент может отрендерить, а так же, что ему нужно для рендеринга.

(react/jsx-no-bind)

Очень распространенная и большая ошибка которую я видел в коде много раз. Не Используйте Bind И Arrow Function В Jsx. Никогда. Больше.
Самое жаркое место в аду ждет того кто пишет .bind(this) в JSX в обработчике событий.
Каждый раз когда компонент рендериться ваша функция будет создаваться заново, и это может сильно затормозить ваше приложение (это связано с тем, что garbage collector будет вынужден запускаться значительно чаще). Вместо .bind(this) вы можете использовать Arrow functions определенным образом:

Читайте также:  Как настроить punto switcher для запоминания паролей

(react/jsx-no-target-blank)

Ошибка связанная с безопасностью. Для меня выглядит очень странно, что люди до сих пор делают эту ошибку. Очень много людей написало очень много статей на эту тему в 2017.
Если вы создаете ссылку с target=’_blank’ атрибутом не забудьте добавить к ней rel=’noreferrer noopener’. Очень просто:

Спасибо вам!

Это все, что я бы хотел рассказать вам в рамках этой статьи. Я буду очень вам признателен, если вы, мои читатели, оставите мне ваш отзыв или комментарий, и поделитесь в нем вашим мнением относительно проблем, которые я описал в этой статье. Так же, вы можете рассказать мне про мои и ваши ошибки в коде и про все, что посчитаете нужным рассказать. Спасибо вам еще раз!

Источник

Не работают стили react

Пришло время сделать наше приложение более привлекательным. Для этого давайте научимся работать со стилями в React.js

Для того, чтобы стилизовать React.js приложение существует огромное количество подходов, библиотек, разнообразных стилизованных компонентов. Мы возьмем самый популярный фреймворк — Bootstrap. Даже когда вы принимаете решение использовать Bootstrap, вы можете легко найти в Гугл множество библиотек, которые интегрировали в себя Bootstrap и дают вам возможность использовать уже готовые стилизованные компоненты. Вы можете выбрать для себя любую из них. Этих библиотек огромное количество.

Мы пойдем классическим путем и будем использовать чистый (классический) css от Bootstrap.

Подключение Bootstrap.

Для этого идем в консоль и устанавливаем с помощью npm сам bootstrap

npm — установит нам библиотеку и теперь мы сможем подключать стили. Для того, чтобы не тянуть стили руками в какой-либо html файл, мы можем подключать в наш проект css стили, как модули.

Это нам позволит сделать webpack, у которого для этого есть специальные возможности (модули), которые позволят подключать стили css в наш проект.

Для этого достаточно в файле App.js написать import и какой именно css модуль мы хотим подключить.

В нашем случае это ‘bootstrap’ . Обратите внимание, что подключаем без всяких слешей, потому что webpack и так поймет, что этот модуль стоит искать в папке -> node_modules. Указываем путь к файлу bootstrap.css.

Подключать файл bootstrap.min.css не имеет смысла, поскольку перед продакшн вы будете все равно минимизировать файлы с помощью webpack.

App.js

Теперь мы можем использовать bootstrap в нашем проекте.

Для того, чтобы дать класс какому-либо элементу нам достаточно написать className = «имя класса»

Например, пометить весь код в контейнер — в файле App.js первому тегу div добавили —

Убедиться, что все работает, вы можете открыв браузер и «исследовав элемент»

Класс добавился. И стили bootstrap прменились к нашим элементам.

Теперь давайте оформим каждый элемент.

Завернем наш header в div классом jumbotron , а самому заголовку дадим класс display-3

Теперь, перейдет к оформлению статей.

В файле Article.js мы добавим стили сразу на всю статью в className=»card» .

Заголовок поместим в header — div className=»card-header» , а сам текст статьи и дату в отдельный div className=»card-header» . Тело статьи в div className=»card-body» ,

Article.js

Немного изменим тело самой статьи и кнопку.

В файле Article.js

Делаем статью на пол экрана и работаем с инлайновыми стилями.

Для того. чтобы дать инлайновый стиль какому-либо элементу, достаточно прописать property style и в двойных фигурных скобках прописать свойство и значение.

Никакой магии в этом нет. Просто одни фигурные скобки говорят о том, что мы используем javascript переменную (выражение, или что-то еще), а вторые скобки говорят, что внутри обычная литеральная нотация.

В принципе, мы могли бы вынести это таким вот образом —

а уже в самом теге оставить только

Можно писать и так и так.

То, что получилось:

Для того, чтобы позиционировать нашу статью по центру добавим: mx-auto элементу

Теперь нам остается убрать маркер списка.

Для этого мы напишем в файле ArticleList.js специальный стиль для тега li , а за одно научимся создавать собственные css-модули.

Нам придется создать отдельный css- файл для нашего ArticleList.js и в таких случаях, чтобы не создавать путаницу в общей папке компонентов, лучше создать для такого компонента отдельную папку!

Подключением файла стилей React — компоненту.

В папке components мы создадим отдельную папку -> ArticleList внутри которой мы будем держать реактовский код index.js, так и стили ArticleList.js

В файл index.js мы вставим весь код из нашего ArticleList.js, только поправим пути:

index.js

и здесь же создадим файл style.css -здесь будут стили данного компонента.

Файл ArticleList.js удаляем.

При этом webpack поймет, что в App.js ->ArticleList — это папка, и коль в ней есть файл index.js, то он возьмет именно этот файл. Поэтому файл index.js не нужно отдельно указывать в этом пути (т.е делать так — > import ArticleList from ‘./ArticleList/index.js’ )
App.js

Теперь добавим стили компоненту в файле style.css

Лучше всего себя показала методология БЭМ (сайт в России с vpn — отдельное спасибо РосКомНадзору) Блок Элемент Модификатор от Яндекса. Вы можете с ней ознакомиться. Мы пока что запишем:

Читайте также:  Не работает менеджер драйверов

style.css

Теперь, для того, чтобы воспользоваться этими стилями. нам необходимо сделать импорт. Мы сделаем это на уровне нашего компонента в файле index.js import ‘./style.css’

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

Нам остается только добавить класс className=»article-list__li» к тегу li

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

Это происходит, потому что webpack ожидал файл ArticleList.js, а теперь он живет в папке.

Чтобы это исправить, достаточно перезапустить сервер -> Ctrl + C

Источник

Практическое руководство по использованию CSS Modules в React приложениях

Привет Хабр! Предлагаю вашему вниманию свободный перевод статьи «Practical Guide to React and CSS Modules» от Tatu Tamminen.

В прошлом веб-разработчики тратили много времени и сил на создание повторно используемых компонентов. Оcобую проблему представлял собой CSS и природа его каскадов. Например, если разработчик создаёт компонент для отображения древовидной структуры, то как он может гарантировать, что CSS класс (например, .leaf), используемый в этом компоненте, не приведёт к побочным эффектам в других частях приложения? Были созданы различные методологии и соглашения, чтобы справиться с проблемами селекторов. БЭМ и SMACSS — широко используемые методологии, которые хорошо выполняют свои задачи, но в то же время далеко не идеальны. В этой статье рассказывается о недостатках таких методологий, основанных на соглашении об именах, о том, что представляют собой CSS Modules, и о том, как эти модули можно использовать в React приложении.

Проблема с каскадами

Давайте создадим повторно используемый компонент select в качестве примера, иллюстрирующего проблемы глобальных стилей. Стилизация элемента напрямую — это плохое решение, поскольку в других местах сайта нам может потребоваться или изначальный нестилизованный элемент, или совсем другая его стилизация. Вместо этого можно использовать синтаксис БЭМ для определения классов:

Если бы новый класс item был создан без префикса select__, то у всей команды могли бы возникнуть проблемы, если бы кто-нибудь захотел использовать такое же имя item. При этом неважно, разработчик ли пишет CSS или же его генерирует какая-то утилита. Использование БЭМ помогает решить эту проблему, вводя контекст для элемента select.

Синтаксис БЭМ является шагом вперёд по направлению к компонентам, так как «Б» в БЭМ расшифровывается как «Блок», а блоки можно интерпретировать как легковесные компоненты. Select — это компонент, у которого есть различные состояния (select—loading) и потомки (select__item).

К несчастью, использование соглашений по именованию и мышление в терминах компонентов не решает всех проблем селекторов. Коллизии имён всё ещё не гарантированы, а семантическая избыточность имён увеличивает риск опечаток и требует дисциплинированной команды, где каждый на все сто процентов понимает соглашения. Опечатки включают в себя использование одного дефиса вместо двух, путаницу между модификатором (—) и блоком (__) и прочее.

CSS Modules спешат на помощь

CSS модуль — это CSS файл, в котором все имена классов и анимаций имеют локальную область видимости по умолчанию.

Ключевая идея здесь — локальная область видимости.

Чтобы проиллюстрировать эту концепцию, давайте создадим JavaScript и CSS файлы компонента.

Это простой пример, который, однако, содержит много всего, происходящего за сценой.

Теперь CSS файл содержит намного меньше шума, чем в БЭМ версии, потому что в нём больше нет префиксов и специальных символов, задающих контекст. Почему же стало возможным удалить префикс .select—, не создавая при этом проблем?

Оператор import в JavaScript файле загружает CSS файл и конвертирует его в объект. В следующем разделе мы рассмотрим, как настроить рабочее окружение, позволяющее импортировать CSS файлы.

Каждое имя класса из CSS файла является свойством объекта. В примере выше это styles.select, styles.icon и т. д.

Если имя свойства — это имя класса, то какое же значение у этого свойства? Это уникальное имя класса, и уникальность обеспечивает то, что стили не «протекают» в другие компоненты. Вот пример хешированного имени класса: _header__1OUvt.

Вы можете подумать: «Какой ужас!» В чём смысл изменения осмысленного имени класса на непонятный хеш? Основная причина в том, что такой идентификатор гарантированно является уникальным в глобальном контексте. Позднее в этом руководстве мы изменим механизм создания идентификаторов, так что они будут иметь более осмысленный вид, но при этом останутся уникальными.

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

  • шаг вперёд по направлению к модульным и повторно используемым компонентам без побочных эффектов,
  • более чистый CSS,
  • избегание монолитных CSS файлов, так как у каждого компонента будет свой файл со стилями.

К недостаткам можно отнести следующее:

  • сложнее читать и понимать DOM,
  • требуется некоторая начальная настройка окружения, чтобы заставить всё это работать.

CSS Modules требуют сборки проекта, но это не проблема, так как различные сборщики поддерживают CSS Modules для JavaScript как на клиенте, так и на сервере. CSS Modules также можно использовать совместно с большинством UI библиотек.

Для простоты в этой статье мы остановимся на сборщике модулей Webpack и библиотеке React.

React, Webpack и CSS Modules

Для быстрого создания приложения можно использовать Create React App.

Следуя инструкциям в документации, мы создадим и запустим новый проект практически мгновенно.

Читайте также:  Не любит работать особенно выполнять грязную работу

Вуаля, и у нас работающее React приложение:

Начальная страница сообщает нам, что нужно редактировать файл App.js.

Используются ли CSS Modules в Create React App? Это можно узнать, взглянув на файл App.js. CSS файл импортируется, но не присваивается никакой переменной, при этом во всех атрибутах className используются строки вместо динамических значений.

С этой точки зрения Create React App не поддерживает CSS Modules, так что нужно изменить конфигурацию, чтобы включить эту поддержку.

Настройка Create React App для поддержки CSS Modules

Чтобы получить доступ к скрытому конфигу сборки, нужно выполнить команду eject. Внимание: если вы сделали это, то вернуться обратно вы уже не сможете.

Теперь можно открыть папку с конфигами для webpack:

Create React App использует webpack для сборки, поэтому webpack.config.dev.js — тот самый файл, который нужно изменить (а также webpack.config.prod.js для настроек продакшна — прим. переводчика).

Найдём раздел, задающий, что делать с CSS файлами (в оригинальной статье используется старый синтаксис конфигов webpack, здесь же я использовал новый — прим. переводчика):

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

Что делают эти загрузчики loaders? В файле webpack.config есть закомментированная секция, описывающая загрузчики стилей и CSS:

postcss-loader применяет autoprefixer к CSS.
style-loader преобразовывает CSS в JS модули, которые инжектят теги .
css-loader разрешает пути в CSS и добавляет ресурсы как необходимые зависимости.

Опция modules: true в настройках css-loader включает поддержку CSS Modules. Параметр localIdentName изменяет шаблон имени класса таким образом, что оно включает в себя имя компонента React, имя класса и уникальный хеш-идентификатор. Это позволит производить отладку намного легче, потому что легко можно идентифицировать все компоненты.

Использование CSS Modules в React

Можно проверить, что конфигурация работает, добавив вызов console.log после оператора import.

Заменяя import ‘./App.css’; на

мы получаем следующий вывод в консоль браузера:

Сейчас классы уникальны, но они не используются в React компонентах. Нужно сделать ещё два шага, чтобы применить стили к React компонентам. Во-первых, нужно изменить имена классов согласно camelCase нотации. Во-вторых, нужно изменить атрибуты className так, чтобы они использовали импортированные классы.

Использовать camelCase нотацию необязательно, но при доступе к классам из JavaScript легче писать styles.componentName, чем styles[«component-name»].

Исходный файл стилей выглядит так:

Больше нет необходимости в префиксах App, поэтому сейчас хороший момент, чтобы удалить их тоже. Модифицированный CSS будет выглядеть так:

Следующий шаг — изменить использование классов в компоненте. Результат будет следующим:

Теперь наш компонент использует CSS Modules.

Как нарушить границы CSS модуля, когда это необходимо

Подход, описанный в предыдущем разделе, является основным для React проектов, но разработчики обычно быстро обнаруживают, что им нужен способ выделять и использовать общие стили. В этом контексте «общие» значит лишь то, что компонент должен наследовать что-то от базовых стилей.

Эту общую информацию могут представлять собой переменные (цвета, размеры шрифта, и т. д.), хелперы (миксины SASS) или utility-классы.

CSS Modules дают возможность композиции с помощью ключевого слова from. Композиция возможна и между классами из разных файлов.

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

Если есть необходимость в использовании переменных, то можно использовать или препроцессор, например, SASS или Less, или настроить поддержку переменных в webpack.

Пример из документации webpack по переменным в CSS:

Этот пример можно изменить, используя собственные имена переменных. Это нужно потому, что переопределение стандартных значений, таких как blue, делает CSS файл менее понимаемым, так как больше нельзя быть уверенным, было ли переопределено какое-то значение или нет.

Заключение

В этом руководстве мы начали с рассмотрения проблем глобального CSS, затем увидели, как CSS Modules улучшают ситуацию, вводя область видимости CSS и заставляя нас думать в терминах компонентов. Также мы рассмотрели, как легко можно начать экспериментировать с CSS Modules, используя React Starter Kit.

CSS Modules используются совместно со сборкой всего фронтэнда, то есть, с поддержкой в браузере нет никаких проблем. Браузеры получают обычный CSS от сервера, так что нет никакой возможности «сломать» сайт, используя CSS Modules. Наоборот, при этому мы только повышаем его надёжность, уменьшая количество потенциальных багов. Webpack с загрузчиками, сконфигурированными для поддержки CSS Modules, не создаёт никаких проблем, так что без сомнений можно рекомендовать этот инструмент к использованию.

Если вы использовали CSS Modules в своих проектах, я (то есть, автор оригинальной статьи — прим. переводчика) хотел бы услышать о вашем опыте!

→ Публикация — свободный перевод статьи «Practical Guide to React and CSS Modules». Автор статьи Tatu Tamminen
→ Исходный код можно найти в react-cssmodules-demo
→ Также заслуживает внимания CSS Modules Webpack Demo

Источник

Оцените статью