Полное руководство для начинающих реагирования

1656546161 polnoe rukovodstvo dlya nachinayushhih reagirovaniya

автор Али Шпиттель

1*tnOVr25yQ2GPzKfpglcxCQ
Фото Александра Эндрюса на Unsplash

Я хочу вернуться к написанию более технического контента. React – одна из моих любимых технологий, поэтому я подумал создать вступление в React! Этот пост требует знания HTML и JavaScript. Я твердо убежден, что вы должны знать это, прежде чем переходить в библиотеки, такие как React!

Что такое React

React – это библиотека JavaScript, созданная в 2013 году командой разработчиков Facebook. React хотел сделать пользовательские интерфейсы более модульными (или пригодными для повторного использования) и более простыми в обслуживании. Согласно веб-сайту React, он используется для «составления инкапсулированных компонентов, управляющих своим собственным состоянием, а затем их компоновки для создания сложных интерфейсов».

Я собираюсь использовать многие примеры Facebook в этой публикации, поскольку они сначала написали React!

Помните, как Facebook перешел от лайков к реакциям? Вместо того чтобы ругать публикации, теперь вы можете реагировать сердечком, смайликом или ругательством на любой пост. Если бы эти реакции в основном осуществлялись в HTML, было бы очень много работы, чтобы изменить все эти предпочтения на реакции и убедиться, что они работают.

Вот здесь на помощь приходит React. Вместо того, чтобы внедрять «разделение проблем», мы имеем другую архитектуру в React. Эта архитектура увеличивает модульность на базе структуры компонента.

Сегодня мы сохраним CSS отдельно, но вы даже можете сделать этот компонент конкретным, если хотите!

React против Vanilla JavaScript

Когда мы говорим о «ванильном» JavaScriptе, мы обычно говорим о написании кода JavaScript, который не использует дополнительные библиотеки, такие как JQuery, React, Angular или Vue. Если вы хотите узнать больше о них и что такое фреймворк, у меня есть публикация о веб-фреймворках.

Несколько быстрых примечаний, прежде чем мы начнем

  • Чтобы сделать этот учебник лучше, приведем несколько примеров кода ... до или после них. Это означает, что мы пропустили некоторый код.
  • Я использую Git diffs в некоторых местах, чтобы показать строки кода, которые будут изменены. Если вы скопируете и оставите, вам нужно удалить файл + в начале строки.
  • У меня есть полный CodePens с завершенными версиями каждого раздела — так что вы можете использовать их, чтобы играть в догонялки!
  • Более расширенные понятия, не являющиеся существенными для учебника, содержатся в блочных кавычках. Это интересные факты!

Настроить

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

Мы будем использовать React CDN, который предназначен только для разработки! Мы также будем использовать Babel CDN, чтобы мы могли использовать некоторые нестандартные функции JavaScript (подробнее об этом мы поговорим позже!).

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js">

Я также сделал шаблон Codepen, который вы можете использовать!

В полном проекте React я разделил бы свои компоненты на разные файлы. В целях обучения мы сейчас объединим наш JavaScript в один файл.

Компоненты

Для этого урока мы создадим виджет статуса Facebook, поскольку Facebook поначалу написал React!

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

Давайте посмотрим на изображение статуса Facebook и разберем разные компоненты в нем.

0*iodL_qOvw1lqk2Yp

Сам статус будет составной. У хронологии Facebook есть много статусов. Мы хотим иметь возможность повторно использовать компонент статуса.

В рамках этого компонента мы будем иметь подкомпоненты или компоненты внутри родительского компонента. Они также можно использовать повторно. Компонент кнопки «нравится» может быть дочерним приложением PhotoStatus компонент и LinkStatus компонент.

Возможно, наши подкомпоненты будут выглядеть примерно так:

0*MK4hJnEE7b9O4gmQ

Мы можем даже иметь подкомпоненты внутри подкомпонентов! Следовательно, группа ругательств, комментариев и распространения может быть отдельной. ActionBar компонент. В нем будут компоненты для комментирования и обмена ругательствами!

0*7wv2ExT3ihc9IEhr

Существует множество способов разбить эти компоненты и подкомпоненты в зависимости от того, где вы повторно будете использовать функциональные возможности в своей программе.

Начинаем

Я хотел начать этот урок с React Hello World — это все-таки традиция! Затем мы перейдем к несколько более сложному примеру статуса.

В наш HTML-файл добавим только один элемент — a div с идентификатором на нем. По условию вы обычно увидите, что у div есть «корень», поскольку он будет корнем нашей программы React!

Если вы пишете код в шаблоне CodePen, вы можете написать этот JavaScript непосредственно в js См. раздел. Если вы вместо этого пишете это на своем компьютере, вам придется добавить тег сценария с типом text/jsxпоэтому:

<script type="text/jsx"><;/script>

Теперь перейдем к нашему React-коду!

class HelloWorld extends React.Component {
  render() {
    // Tells React what HTML code to render
    return <h1>Hello World</h1>
  }}
// Tells React to attach the HelloWorld component to the 'root' HTML div
ReactDOM.render(&lt;HelloWorld />, document.getElementById("root"))

Все, что происходит, это то, что Hello World отображается как H1 на странице!

Давайте разберемся, что здесь происходит.

Во-первых, мы используем класс ES6, который наследуется от React.Component класс. Это шаблон, который мы используем для большинства наших компонентов React.

Далее, в нашем классе есть метод — и его специальный метод называется render. React ищет render способ решить, что отразить на странице! Название имеет смысл. Что бы от этого ни вернулось render метод, воспроизведенный этим компонентом.

В этом случае мы возвращаем H1 с текстом Hello World — это именно то, что обычно было бы в файле HTML.

Наконец, имеем:

ReactDOM.render(<HelloWorld />, document.getElementById("root"))

Мы используем функциональность ReactDOM, чтобы присоединить наш компонент реакции к DOM.

React использует то, что называется виртуальной DOM, которая является виртуальным представлением DOM, с которой вы обычно взаимодействуете в Vanilla JavaScript или JQuery. Это reactDOM.render отображает эту виртуальную DOM к фактической DOM. За кулисами React выполняет много работы, чтобы эффективно редактировать и повторно отображать DOM, когда что-то в интерфейсе нужно изменить.

Наш компонент, <HelloWorld />, похоже на HTML тег! Этот синтаксис – part JSX, являющийся расширением JavaScript. Вы не можете его использовать в браузере. Помните, как мы используем Babel для нашего JavaScript? Babel транспилирует (или конвертирует) наш JSX в обычный JavaScript, чтобы браузер мог понять его.

JSX на самом деле необязателен в React, но вы увидите, что он используется в подавляющем большинстве случаев!

Тогда мы используем встроенный JavaScript document.getElementById чтобы получить наш корневой элемент, который мы создали в нашем HTML.

В общем, в этом ReactDOM.render заявление, мы добавляем наше HelloWorld компонент к нашему div который мы создали в нашем HTML-файле.

Стартовый код

Ладно — теперь, когда мы сделали Hello World, мы можем начать работу с нашим компонентом Facebook.

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

Давайте начнем с «твердой кодировки» HTML для виджета:

С некоторыми добавленными CSS это выглядит так:

0*iYUATDXs_LeCtVv9

Вот Codepen с полным стартовым кодом.

Для этого учебника мы создадим четыре компонента: a Status компонент, который будет родительским, a Like компонент, который будет охватывать логику симпатии, и Comment компонент, содержащий логику для ввода комментария. The Like компонент также будет иметь ребенка LikeIcon которые отображаются или скрываются, когда вы переключаете кнопку «нравится».

Архитектура компонентов

Давайте поделим написанный нами HTML-код на эти компоненты.

Мы начнем с оболочки компонента, а также воспроизведем ее, чтобы убедиться, что она работает!

Одно интересное примечание по поводу вышесказанного состоит в том, что нам пришлось изменить атрибуты «class» на «className». Класс уже означает что-то в JavaScript – это для классов ES6! Некоторые атрибуты называются в JSX иначе, чем в HTML.

Мы также можем удалить содержимое нашего HTML, оставив только элемент с корневым идентификатором – родительское «содержимое» div предназначено только для стилизации!

<body>   <div class="content">     <div id="root"></div>   </div> </body>

Вот HTML, который будет входить в компонент Status. Заметьте, кое-что из оригинального HTML-кода еще нет — вместо этого он войдет в наши подкомпоненты!

Давайте создадим второй компонент, а затем включим его в наш Status компонент.

class Comment extends React.Component {   render() {     return (       <div>         <textarea className="form-control" placeholder="Write a comment..." />          <small>140 Remaining</small>       </div>       )    } }

Вот компонент для нашего комментария. У него есть наше textarea для ввода, а также текст с оставшимся количеством символов. Обратите внимание, что оба завернуты в a div. Это связано с тем, что React требует от нас завернуть все содержимое компонента в один HTML-тег. Если бы у нас не было родителей div мы бы вернули а textarea и а small тег.

Итак, теперь нам нужно включить этот компонент в наш Status компонент, потому что это будет наш подкомпонент. Мы можем сделать это, используя тот же синтаксис JSX, который мы использовали для воспроизведения компонента Status!

Ладно, теперь нам просто нужно сделать то же самое для наших предпочтений:

Тогда нам нужно включить его в наш оригинал Status компонент:

Круто, сейчас мы реактировали наш уникальный HTML, но он все равно ничего не делает. Начнём это исправлять!

В общем код из этого раздела будет выглядеть так, как CodePen.

Состояние и реквизит

У нас есть два разных взаимодействия пользователей, которые мы хотим реализовать:

  • Мы хотим, чтобы значок «нравится» появлялся, только если нажата кнопка «нравится».
  • Мы хотим, чтобы количество оставшихся символов уменьшалось по мере смены личности.

Начнём над этим работать!

Реквизит

Представьте себе, что мы хотели, чтобы наше поле для комментариев позволяло разное количество букв в разных местах. Например, в статусе мы хотим, чтобы пользователь мог написать ответ из 200 букв. Однако на картинке мы хотим, чтобы они могли написать ответ из 100 символов.

React позволяет нам передавать props (сокращенно от свойства) с PictureStatus компонент и Status компонент, чтобы указать, сколько букв мы хотим разрешить в нашем ответе, вместо того, чтобы иметь два разных компонента комментариев.

Синтаксис реквизитов выглядит следующим образом:

<Comment maxLetters={20} /> <Comment text="hello world" /> <Comment show={false} /> 
let test="hello world" <Comment text={test} />

Реквизиты смотрятся как атрибуты HTML. Если вы передаете строку через props, вам не нужны скобки. Любой другой тип данных или переменная должны быть в скобках.

Затем в нашем компоненте мы можем использовать наши реквизиты:

console.log(this.props.maxLetters)

Они соединены вместе в props атрибут экземпляра, чтобы к ним можно было получить доступ this.props.myPropName.

Итак, давайте изменим жестко закодированные 140 символов, чтобы их можно было изменить вне компонента!

Сначала мы изменим место, где создаем компонент Comment в компоненте Status (обратите внимание, что некоторый код пропущен):

class Status extends React.Component {   ...       <div className="card-footer text-muted">         <Comment maxLetters={280} />       </div>      </div>;    </div>   )  } }

Затем мы изменим жестко закодированный лимит в 140 символов в комментарии.

class Comment extends React.Component {   ...     <div>      <textarea className="form-control" placeholder="Write a comment..." />     <small>{this.props.maxLetters} Remaining</small>;     </div>    ... }

государство

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

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

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

Мы хотим, чтобы это состояние создавалось всякий раз, когда мы создаем новый экземпляр компонента, поэтому для его создания будем использовать конструктор класса ES6. Если вы хотите быстро обновить классы ES6, MDN – отличный ресурс!

State будет объектом с любыми парами ключ-значения, которые мы хотим включить. В этом случае нам требуется characterCount, сколько символов ввел пользователь. Мы установим это на ноль:

class Comment extends React.Component {     constructor () {       super()       this.state = { characterCount: 0 }     } ...

Теперь давайте вычтем это из maxLetters prop, так что мы всегда знаем, сколько символов у нас осталось:

<small>{this.props.maxLetters - this.state.characterCount} Remaining&lt;/small>

Если увеличить characterCountколичество оставшихся символов уменьшается.

Но ничего не происходит, когда вы печатаете! Мы никогда не меняем ценность characterCount. Нам нужно добавить обработчик события к textarea чтобы мы изменили characterCount когда пользователь вводит.

Обработчики событий

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

Мы собираемся добавить a onChange обработчик нашим textarea. Внутри него мы разместим ссылку на метод обработки событий, который будет запускаться каждый раз, когда пользователь введет textarea.

<textarea className="form-control" placeholder="Write a comment..." onChange={this.handleChange}/>

Теперь нам нужно создать a handleChange метод!

class Comment extends React.Component {     constructor () {      super()      this.state = { characterCount: 0 }     }         handleChange (event) {       console.log(event.target.value)     } ...

Сейчас мы просто console.log-ing the event.target.value. Это будет работать так же, как и в JavaScript без React (хотя если вы погрузитесь немного глубже, объект происшествия будет несколько иным). Если вы посмотрите на консоль, мы распечатаем то, что вводим в текстовом поле.

Теперь нам нужно обновить characterCount атрибут в состоянии. В React мы никогда не меняйте непосредственно состояниепоэтому мы не можем сделать что-либо подобное: this.state.characterCount = event.target.value.length. Вместо этого нам нужно использовать this.setState метод.

handleChange (event) {    this.setState({ characterCount: event.target.value.length }) }

Но! Вы получаете ошибку — «Uncaught TypeError: this.setState не является функцией». Эта ошибка говорит нам о необходимости сохранить контекст класса ES6 в обработчике событий. Мы можем сделать это посредством связывания this к методу в конструкторе! Если вы хотите больше прочесть об этом, вот хорошая статья.

class Comment extends React.Component {    constructor () {      super() this.handleChange = this.handleChange.bind(this) ...

Хорошо! Мы почти на месте. Нам просто нужно добавить возможность переключения like появляется.

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

class Like extends React.Component {     constructor() {       super()       this.state = { liked: false }      } ...

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

class Like extends React.Component {   constructor() {     super()     this.state = { liked: false }    this.toggleLike = this.toggleLike.bind(this)    } 
  toggleLike () {     this.setState(previousState => ({ liked: !previousState.liked    }))    } ...

Разница здесь заключается в том, что функция обратного вызова this.setState получает параметр — previousState. Как вы наверняка можете догадаться из названия параметра, это значение состояния раньше this.setState это называется. setState является асинхронным, поэтому мы не можем зависеть от использования this.state.liked внутри него.

Теперь нам нужно:

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

б) показывать значок «Нравится» только тогда, когда liked правда

Прекрасно! Теперь все наши функции на месте!

Бонус: Функциональные компоненты

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

В таком случае наша LikeIcon может выглядеть примерно так:

Мы просто возвращаем пользовательский интерфейс пользователя вместо использования render метод!

Вот CodePen, реализующий этот рефакторинг.

Шпаргалку

Я люблю шпаргалки, поэтому я сделал их с содержанием этой публикации:

0*jH9Vm3B7WVGr09-6

Вы также можете скачать его в формате PDF здесь!

Следующие шаги

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

Если вы хотите просмотреть все CodePens из этого учебника, вот коллекция.

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

Кроме того, вот некоторые другие отличные места для изучения React:

Поддерживать связь

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

Первоначально опубликовано на zen-of-programming.com.

Добавить комментарий

Ваш адрес email не будет опубликован.