Эта серия статей написана на основе заметок, использованных во время семинара, организованного OKE Software Poland в Гданьске, Польша. Он не претендует на то, чтобы быть всеобъемлющим и полным учебным пособием для всех, но он будет использоваться для семинара, предназначенного для разработчиков, у которых нет опыта создания SPA с использованием React. Выкладываю сюда, так как думаю, что кому-то это может быть полезно. Пожалуйста, не стесняйтесь поправлять меня, если найдете какую-то ерунду. Также имейте в виду, что английский не является моим родным языком, поэтому простите меня за любые грамматические и лингвистические ошибки. Наслаждайтесь!

Кстати вот предыдущая часть:



План

Часть 7. Жизненный цикл компонента, подключение к API.

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

Все благодаря Войцеху Надурскому 😍 теперь у нас есть доступный API. Это под:

https://github.com/wojciech-bilicki/MarvelApp/tree/step7-with-server-added в папке server. Пожалуйста, ознакомьтесь с этой веткой или просто загрузите сервер. В нем есть файл readme, чтобы рассказать вам, как его запустить. Кроме того, когда вы запускаете сервер, вы можете найти полную документацию по доступным конечным точкам по адресу: http://localhost:8001/docs.

Жизненный цикл

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

Мы вам позвоним

Какими бы раздражающими они ни были, это стандарт в нашей отрасли. Было бы безумием каждый час звонить в компанию, которую вы пытаетесь заполучить, и спрашивать:

То же самое касается жизненного цикла нашего компонента. Он должен быть смонтирован в виртуальный DOM, он должен быть отрендерен, он должен реагировать на изменение состояния или свойств. Мы не просим React:

Чувак, ты уже установил этот компонент? У вас есть? У вас есть? У вас есть?

Он называется Инверсия контроля. Мы позволяем реагировать сообщать нам о событиях, происходящих внутри его механизма. И это прекрасно работает!

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

  • конструктор, getInitialState -> Что ж, довольно очевидно, что он вызывается первым при создании компонента. Звонил один раз.
  • getDefaultProps -> набор свойств по умолчанию для данного компонента. Может быть, мы хотели бы, чтобы наш ввод числа всегда по умолчанию был равен нулю? Звонил один раз.
  • componentWillMount -> вызывается непосредственно перед отправкой компонента для монтирования в виртуальный DOM. Звонил один раз.
  • componentDidMount -> вызывается сразу после того, как компонент был смонтирован в виртуальный DOM. Это место, где вы хотите вызвать свой API для передачи данных в этот и дочерние компоненты. Мы будем часто это использовать.
  • componentWillRecieveProps -> вызывается непосредственно перед тем, как новые реквизиты от родителя передаются компоненту. Если у вас есть какое-то состояние, основанное на свойствах, самое время пересчитать и/или установить его. Например, у вас есть вход, который поддерживает свое собственное значение, но сбрасывается каждый раз, когда от родителя поступают новые реквизиты. Вот место для вызова setState со значением, которое вы получаете от родителя. Вызывается каждый раз, когда родитель передает новые реквизиты.
  • shouldComponentUpdate --> очень интересный обратный вызов. Мы можем использовать его для настройки производительности. Он должен возвращать логическое значение. Если у вас есть компонент, который никогда не обновляется (например, логотип idk вашей компании или статический значок), вы можете вернуть false, чтобы сообщить React, что этот компонент не должен обновляться ни при каких обстоятельствах, или вы можете реализовать более сложную логику для проверки изменений состояния. переход и решить, следует ли перерисовывать этот компонент. Вызывается каждый раз, когда родитель передает новые реквизиты;
  • componentWillUnmount -› этот обратный вызов может использоваться для очистки любых ресурсов или отключения любых внешних обработчиков событий. Звонил один раз.
  • render -> вызывается каждый раз, когда компонент должен отрендериться.

Хорошо, мы, вероятно, внесем некоторые критические изменения по мере продвижения, но нас это устраивает.

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

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

  1. Мы используем extends React.Component для создания нашего компонента
  2. <Props> исходит из FlowType, что означает, что мы не заботимся о типизации состояния, а свойства должны быть типизированы как Props type. Это новый синтаксис FlowType для компонентов React.
  3. Мы добавили обсуждаемые хуки просто для того, чтобы показать, как они работают.
  4. Нам пришлось предоставить функцию рендеринга, которая возвращает разметку jsx для нашего компонента, которая почти такая же, как и функциональная, за исключением того, что нам нужно было добавить this перед использованием реквизита. Мы также можем выполнить деконструкцию реквизита, чтобы избавиться от this. Игра слов.

Хорошо, давайте добавим аксиомы в наш проект и на самом деле используем наш хук, чтобы сделать что-то полезное.

yarn add axios

Хорошо, давайте сначала изменим наш App.js, чтобы избавиться от данных, загружаемых из файла .json:

Здорово. Теперь мы получаем некоторые ошибки в консоли, так как герои больше не предоставляются в качестве реквизита, но это скоро будет исправлено. Итак, давайте избавимся от всех хуков, кроме componentDidMount, и изменим его на:

Итак, что мы сделали здесь, так это добавили определение type State в строку 14, а также использовали axios для выполнения HTTP-вызова GET к нашему API под URL-адресом heroes. После того, как это успешно разрешено в then части, мы добавляем результат в состояние. Было не так уж сложно, не так ли?

Да, давайте также исправим нашу карту HeroCard, чтобы она снова отображала изображения:

Хорошо, мы снова на ходу. Эта часть была намного короче остальных.

Теперь давайте попробуем добавить в микс раздел MyHeroes.

Давайте обновим наш Master.jsx до:

Мы исправим некоторый уродливый код, который мы увидим позже. Например, мне очень не нравится, как сейчас выглядит наш componentDidMount. Хорошо, что касается компонента MyHeroes, он скорее повторяет то, что мы уже сделали:

Здесь стоит подчеркнуть, что мы используем flexbox для создания сетки из двух столбцов (для списка героев и для компонента MyHeroes) и что мы используем условный рендеринг в методе render для компонента MyHerores, чтобы показать его пустое состояние. Мы просто рендерим информацию о том, что героев не добавили. React позволяет очень легко реализовать такой шаблон. Похоже, мы готовы добавить героев в избранное. Давайте сделаем именно это.

Сначала мы должны реализовать обратный вызов в родительском (Master) компоненте, чтобы передать его дочерним (HeroCards):

и, естественно, использовать его в качестве обратного вызова в нашем дочернем компоненте:

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

Хорошо, пока все хорошо, но мне очень не нравится код в нашем Master.jsx. Давайте создадим еще один файл и назовем его api.js.api.jsx. Мы будем использовать промисы и цепочку промисов, чтобы предоставить данные для нашего основного компонента. Axios также имеет эту фантастическую функцию установки конфигурации по умолчанию, которую мы будем использовать, чтобы наш код оставался чистым:

Хорошо, теперь давайте добавим немного внешнего вида нашему любимому компоненту героя и создадим файл FavouriteHero.jsx:

и, конечно же, нам нужно обновить наши Master и MyHeroes, чтобы передать обратный вызов onDelete на два уровня ниже компоненту FavouriteHero, чтобы иметь возможность удалять героев.

Итак, есть еще два компонента, которые я хотел бы добавить, прежде чем мы закончим с этим и перейдем к Redux. Добавим маршруты для HeroDetails и Comics:

Через секунду мы обработаем идентификаторы, переданные компонентам Detail и Comics, иначе, чем в Master.

Хорошо, давайте сначала сделаем компонент Details:

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

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

и конечно же ComicsThumb.jsx:

А что касается деталей комикса, вот Comics.jsx. Я оставляю стилизацию на ваше усмотрение, так как это не является основной задачей этого семинара:

Теперь осталось соединить детали. Нам бы хотелось, чтобы, когда мы нажимаем на портрет нашего героя, мы переходили к подробностям о герое. То же самое для комиксов. Хорошо, давайте сначала исправим наш HeroCard.jsx:

Ну и конечно же ComicsThumb.jsx:

Вы можете перейти на TabBar.jsx и добавить ссылку на логотип для возврата на главную страницу. Что здесь остается делать? Конечно, мы могли бы изменить стиль. Мы могли бы добавить компонент со списком всех комиксов. Мы могли бы написать больше тестов и улучшить охват FlowType по всему проекту, но все это было бы довольно повторяющимся по сравнению с тем, что мы уже сделали. Я лучше перейду на Redux, который ВАМ МОЖЕТ НЕ НУЖНО. Мы в значительной степени закончили приложение, даже не зная, что такое Redux, поэтому не стоит просто прыгать на шумихе и действительно думать, выиграет ли ваш проект от Redux или это только усложнит?

Как вы видели, React не так уж и сложен. У него нет очень богатого или сложного API (привет, Angular 1.x). Он использует вещи, которые вы уже знаете, и не добавляет запутанного синтаксиса (ng-*). Это деклеративно, это просто. Вы можете думать о своем приложении как о кусочках логотипа, которые вы просто связываете вместе. Легко добавлять такие вещи, как пустые состояния или загрузчики. Вы обязательно должны дать ему шанс. Есть еще много других вещей, связанных с React, о которых вам следует узнать, но Medium и YouTube — фантастический источник знаний, и вам обязательно нужно получить больше! Увидимся в следующем!