Больше JS, чем React как фреймворк использует возможности языка

React практически не добавляет к нативному JS внешней абстракции. Поэтому разработчику необходимо хорошо разбираться в основах языка.

В этой статье разберем самые нужные для React концепции JavaScript.

Вхождение в React

Первое что мы видим после создания проекта с create-react-app – это классы компонентов:

Здесь много концепций, которые не связаны с фреймворком напрямую: ключевое слово class, наследование, методы, интерполяция, импорт и экспорт. Кажется, без понимания нативного JavaScript в React делать нечего. Начнем с самых простых вещей и увидим, что в React больше JS, чем мы думали.

Стрелочные функции

Стрелочные функции – одно из недавних приобретений JavaScript. Они делают код намного короче и проще.

Строковые литералы

Мы привыкли к такому синтаксису конкатенации строк в JS:

А шаблоны строк позволяют использовать интерполяцию с помощью обратных кавычек и нотации $<> :

Их можно использовать также для реализации многострочности:

Компоненты

React и JS-классы

Классы появились в языке относительно недавно, заменив собой цепочки прототипов. Один из способов определения компонентов в React основан именно на них.

Оператор new вызывает конструктор класса, который создает новый объект, обладающий некоторыми свойствами и методами.

Оператор extends позволяет одному классу наследовать от другого. Класс-наследник может расширять функциональность родителя собственными методами.

Все компоненты React наследуют об базового класса Component , импортированного из пакета React.

Метод render является обязательным, так как класс Component вызывает его для отображения чего-либо в браузере. Без расширения базового компонента не получится использовать методы жизненного цикла, например, componentDidMount , а также метод setState , управляющий локальным состоянием.

Таким образом, использование JS-классов позволяет расширить существующий функционал базового компонента и получить доступ к API React.

Сокращенный синтаксис

Если компонент имеет собственные методы, их необходимо привязать в конструкторе. Там же создается объект состояния:

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

Использование стрелочных функций JavaScript позволяет не биндить методы. А если конструктор не использует props , его вообще можно убрать, определив состояние непосредственно как свойство класса. (Свойства класса еще не входят в стандарт JS.)

Компоненты-функции

Некоторые компоненты должны получать входные данные и просто возвращать отображаемые HTML-элементы без управления состоянием. Такие компоненты называются функциональными, они менее сложны и более удобны.

Для их создания можно использовать стрелочные функции JS.

Выражения импорта и экспорта

Любой create-react-app проект начинается с инструкций import и export:

Переменные, компоненты или функции, объявленные в одном файле:

можно импортировать в другой:

Весь экспорт можно получить в виде единого объекта:

Чтобы избежать совпадений имен при импорте используются псевдонимы.

Есть также вариант импорта/экспорта по умолчанию. Он используется, если экспортируется всего одна переменная или если требуется выделить главную функциональность модуля.

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

Можно сочетать дефолтный и именованный экспорт:

Это основные функции ES6 модулей. Они помогают организовать код, удобно поддерживать его, тестировать и повторно использовать.

JavaScript detected

Деструктуризация и spread-оператор

Если требуется получить доступ к большому количеству свойств из state или props , можно использовать новую возможность JavaScript – деструктуризацию.

Входящий параметр можно деструктурировать прямо в сигнатуре функции.

Для сохранения незадействованных при деструктурировании свойств объекта существует параметр rest .

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

Map, Reduce и Filter

Вывести в JSX-коде одну переменную или свойство объекта нетрудно, нужно просто обернуть их в фигурные скобки. Но как вывести список? В React не существует какого-то специального API или атрибута для рендеринга коллекции элементов, нужно использовать нативные возможности языка.

Можно еще сократить код, используя стрелочные функции:

JS-метод map просто проходит по массиву и возвращает JSX-код для каждого элемента. Иногда вместо map следует применять filter или reduce .

Тернарный оператор

В JSX нельзя напрямую использовать конструкцию if. else , но можно воспользоваться тернарным оператором JS:

Функции высшего порядка

Рассмотрим пример фильтрации списка пользователей на основе значения поля ввода.

Выделим фильтрующую функцию из компонента, чтобы было удобнее ее тестировать и передадим в метод filter как параметр.

Но doFilter ничего не знает о свойстве query . Чтобы все заработало, мы превратим ее в функцию высшего порядка.

Стрелочные функции сделают запись более краткой.

Теперь doFilter можно экспортировать из файла и тестировать изолированно от компонента.

Поняв этот принцип, вы без труда разберетесь в React-компонентах высшего порядка.

Больше JavaScript, чем React

Фреймворк React имеет тонкую прослойку аутентичного API, но все остальное – это чистый JavaScript. Давайте убедимся в этом, отрефакторив компонент высшего порядка, а заодно повторим изученное.

Это компонент-обертка для отображения индикатора загрузки. Вы уже можете видеть деструктурирование и работу spread-оператора, который позволяет передать все неиспользованные свойства из объекта props.

Первым шагом рефакторинга будет превращение компонента в функциональный:

Переносим деструктуризацию в сигнатуру параметра и используем стрелочную функцию для краткости:

Добавим тернарный оператор:

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