Введение в React, часть 1

Опубликовано: 2020-07-02

Мы уже говорили в этом блоге о новом стеке разработки WordPress и революции, которая с ним связана, как для самой платформы, так и для разработчиков, которые теперь вынуждены изучать новые вещи. Например, недавно я опубликовал пост, объясняющий, как использовать пакет @wordpress/scripts для расширения Gutenberg и добавления кнопки в его пользовательский интерфейс. Как автор, я люблю писать уроки, потому что я могу поделиться чем-то, что я хорошо знаю, и я чувствую, что мы можем учиться все вместе.

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

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

Функциональное программирование

Прежде чем говорить о React, я думаю, стоит уделить пару минут разговору о функциональном программировании , поскольку многие используемые нами сегодня фреймворки опираются на его принципы. И React (наряду с Redux) не исключение.

Функциональное программирование — это парадигма программирования, в которой программы строятся путем применения и составления функций. Вы можете подумать, что «программирование» всегда сводилось к созданию и запуску функций, верно? Не совсем. Потерпите меня.

Рассмотрим, например, объектно-ориентированное программирование. В ООП программы строятся путем создания и компоновки объектов, которые могут содержать данные в виде атрибутов или полей и код в виде методов или процедур. Видеть? Не функции, а объекты.

Так что же делает функциональное программирование особенным? Что ж, есть несколько аспектов, характеризующих функциональное программирование: чистые функции, ссылочная прозрачность, неизменность, функции как объекты первого порядка, функции высшего порядка и т. д., и я рекомендую вам изучить их самостоятельно (или, если хотите, я к, мы можем поговорить о них в следующих постах). Но, чтобы этот пост был коротким, сегодня мы просто сосредоточимся на одной функции…

Чистые функции

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

  1. Он всегда дает один и тот же результат при использовании одних и тех же аргументов.
  2. Не имеет побочных эффектов

Например, это не чистая функция:

 let previousName = 'David'; function greet( name ) { if ( previousName !== name ) { console.log( `Hello, ${ name }!` ); } else { console.log( `Welcome back, ${ name }!` ); } previousName = name; }

потому что у него есть несколько побочных эффектов. А именно, он изменяет глобальную переменную (побочный эффект 1) и выводит некоторый текст в консоль (побочный эффект 2).

Другая нечистая функция заключается в следующем:

 function createElement( name ) { const id = Math.random(); return { id, name }; }

потому что, как видите, это не всегда приводит к одному и тому же результату. Каждый раз, когда кто-то вызывает createElement с определенным именем, результат получается разным. Ведь атрибут id генерируется через Math.random

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

Компоненты в React

Что должны делать чистые функции и функциональное программирование? Что ж, давайте посмотрим, сможем ли мы вывести их отношения…

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

 class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for { this.props.name }</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } }

Довольно просто и даже понятно, не так ли?

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

Gif женщины, делающей насмешливую гримасу

Да, ты абсолютно прав. Выглядит нехорошо… неужели мы зря потратили время на разговоры о функциональном программировании?

Взгляните на предыдущий компонент еще раз. На что это похоже? Что оно делает? Ну, это класс с одним методом ( render ), который генерирует некоторый HTML для отображения списка покупок. Этот список покупок всегда один и тот же (да, это простой пример), но у него есть одна переменная часть: его заголовок, где класс, похоже, использует внутреннее свойство this.props.name .

Итак, если мы еще ничего не знаем о React и только смотрим на код и пытаемся сделать вывод, что он делает, мы видим следующее:

  1. Компонент может получить «имя». Мы не знаем точно, как он получил это имя, но мы знаем, что это так. В конце концов, this.props.name — довольно хорошая подсказка.
  2. Метод render создает некоторый HTML для рендеринга (статического) списка «элементов покупок»: Instagram , WhatsApp и Oculus .
  3. Результирующий HTML не является на 100% статичным; он использует «имя», которое может варьироваться в зависимости от значения свойства.

Видишь, куда я иду?

Функции компонентов в React

Мы только что описали чистую функцию! У нас есть компонент, который принимает значение ( name ) и выдает четко определенный вывод (HTML). Означает ли это, что мы можем отказаться от ООП и реализовать предыдущий компонент как функцию?

Гифка, на которой мужчина сомневается в своих мыслях

Конечно! Чрезмерно сложный класс, который мы только что видели, можно переписать как более простую и понятную чистую функцию, которая получает props и возвращает HTML:

 const ShoppingList = ( props ) => ( <div className="shopping-list"> <h1>Shopping List for { props.name }</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> );

Это то же самое, что и у нас, но намного проще. Я бы даже осмелился сказать, что это самая простая вещь, которую я могу реализовать как программист: компонент React — это не что иное, как функция, которая принимает некоторые реквизиты и создает на выходе HTML .

И это как раз первый урок, который вы должны усвоить: ваш компонент React — это чистая функция : props на входе, HTML на выходе. Компонент не должен выполнять асинхронные функции для выборки данных (поскольку это побочные эффекты). Компонент также не может изменять свойства, которые он получает (неизменяемость).

Итак, еще раз: компонент просто принимает некоторые реквизиты и создает вывод HTML. Период.

Но подождите, если компонент такой простой, как мы можем сделать с ним что-то полезное? Что ж, следите за обновлениями, потому что мы поговорим об этом в следующем посте!

Избранное изображение Джозайи Вайса на Unsplash.