Уроки React. Урок 3

logo_og

Теперь для поддерживаемости вашего кода нужно указать какие же props/каких типов может ожидать наш компонент.

В файл comments.js добавляем:

Мы ожидаем что нам придут comments, мы пишем об этом на 2 строчке сверху в коде.

.shape – описывает какого вида могут быть данные.

В нем должен быть text и user, к примеру. Таким образом вы описываете что хотите получить.

Также добавим такую запись в Article.js

Изменим для начала первую строку на

Класс будет выглядеть таким образом:

Заметим, что из компонента в компонент у нас повторяется один и тот же функционал, т.е. Article и Comment List выполняют одну и туже логику в плане открытия/закрытия статей/комментариев. Та же самая toggleOpen, скорее всего, повторится еще много раз в наших компонентах. Давайте переиспользуем наш код. Самый простой метод это – mixins.

Создадим файл mixins/toggleOpen.js и опишем что он будет подмешивать в наш компонент.

Этот синтаксис поддерживается в старых компонентах React, но не поддерживается в ES6 и в Functional Components. Также возможно встретить старый синтаксис такой как этот, назовем файл ArticleOld.

Хорошей практикой является написание компонентов максимально инкапсулированных, чтобы стороннему разработчику не пришлось лезть в их код при работе с приложением.
Почему в ES6 не использует mixins, во-первых это противоречит самой спецификации классов. mixins это множественное наследование, оно запрещено во множестве серьезных языков программирования. Наследование функциональности от нескольких родителей ведет к появлению неочевидности и непрозрачности кода, а также к ошибкам. Во-вторых, в двух разных mixins нельзя добавлять два метода с одинаковым названием. Поэтому в современном React это не используют.

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

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

Также сделаем импорт декоратора в CommentList

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

В декоратор вынесем State, toggleOpen, для этого уберем их из файла CommentList. Для того чтобы наш компонент знал о состояниях, которые мы описываем, мы передаем состояния как props в строке 16. Таким образом в наш компонент попадет не только комментарии, но и isOpen, toggleOpen . Добавим запись об этом в CommentList

Также удалим строки

А строчку c OnClick изменим так:

Такой подход более удобный и явный. Так будет выглядеть CommentList

Написанные нами компоненты достаточно простые. Давайте рассмотрим некий жизненный цикл компонентов в React.
165

Первый этап – это момент до инициализации компонента, до его появления в DOM дереве. На схеме этот блок отмечен красным квадратом. Например, где-то было принято решение о render этого компонента, возможно это происходит впервые. Начнем со второй ступени этого блока, getInitialState (в новом синтаксисе это просто state). State может зависеть от props., но это довольно плохая практика.

После создания начального состояния вашего компонента вызовется componentWillMount (), в нем будет доступно все this.props, this.state, все что нужно чтобы сделать render вашего компонента.

Далее идет render, строится виртуальный DOM, далее, когда мы готовы его вставить в реальный DOM вызывается componentDidMount.

Иногда как в случае с CommentList наш компонент содержит еще несколько компонентов, например, Comment в нашем случае, они в свою очередь тоже имеют эти Lifecycle методы. Каков же порядок выполнения? Сначала отработает родительский componentWillMount, потом render, потом дочерние componentWillMount, потом метод render закончился и начинает встраиваться в DOM дерево. Сначала отработает componentDidMount дочерних компонентов и только когда все дочерние компоненты будут готовы, будет вызван родительский componentDidMount.

Следующий этап component Lifecycle это этап обновления, выделен зеленым. Т.е. у него будет меняться state, приходить новые props, и на это мы тоже можем подписываться. Иногда состояние компонента зависит от props, т.е. вам необходимо следить, когда они обновляются и менять state для поддержки его в актуальном состоянии.

Поэтому в ComponentWillReceiveProps вы можете вызвать setState и тогда в ComponentWillUpdate у вас будут и новые props и новые state, т.о. приложение не будет делать render 2 раза. Далее произойдет render и ComponentDidUpdate (где мы уже обновились). В ComponentDidUpdate есть доступ и к старым, и к новым props, новые будут храниться в this, а старые просто как аргумент (prevProps, nextProps).

ComponentWillReceiveProps – тут есть доступ до старых Props и к новым;

shouldComponentUpdate – об этом методе поговорим в следующих уроках

ComponentWillUpdate – тут есть доступ и к новым props и к новым state

Так происходит до тех пор, пока компонент не обновиться полностью и произойдет

componentWillUnmount – это значит что компонент все еще находиться в DOM, но скоро мы его от туда уберем. Это распространенная ситуация для очистки каких-либо подписок.

Для лучшего понимания процесса работы Lifecycle добавим следующий код в class CommentList нашего компонента CommentList:

Результаты работы можно наблюдать в консоли.

На протяжении Lifecycle в компонент находящийся в DOM дереве могут приходить новые props, а он в свою очередь будет постоянно обновляться. Вспомним о ключах их прошлых уроков, которые мы писали для наших Articles. Если мы не используем их, то каждый раз, когда статья будет удаляться из списка наш компонент будет обновляться, т.е. не будет проходить все этапы цикла. Но если меняется ключ это уже причина для переинициализации всего компонента полностью. Если где-то меняется ключ значит React уберет предыдущий и вставит новый, это удобно если вы используете сторонние библиотеки такие как D3, чтобы не следить за всеми обновлениями вручную, вы просто убираете старое и строите новое.

Иногда необходимо работать с реальным DOM, сам React знает его структуру, необходимо только запросить ее у него. Для этого используется ref.

Например, добавим ref в CommentList для элемента с Link:

Также напишем следующий код в этом же файле:

Таким образом мы получили доступ до реального DOM элемента с Link и можем с ним работать. Как работать с JQuery компонентами? Создадим файл для этого JqueryComponent. Пишем следующее:

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

Поговорим далее о потоках данных. Не всегда мы можем организовать его в одном направлении, иногда будет использоваться обратный поток данных. По умолчанию в React все данные передаются сверху вниз, но иногда есть необходимость управления родительским компонентом из дочернего. Например, мы хотим, чтобы в один момент времени была открыта одна статья, а другие были закрыты автоматически. Т.е. информация должна храниться сверху в родителе, т.е. необходимо организовать reverse data flow, т.к. компоненты про друг друга ничего не знают.

Для начала мы уже не можем использовать Functional Component Article List, так как у нас появиться Functional list. Начнем работу над кодом ArticleList.

Изменяем код импорта в первой строчке, создаем class вместо функции, добавляем render. Также не забудьте изменить import на 2 строке. Теперь задаем state на 5 строчке. Сначала нам необходимо знать какая статья открыта, опишем это на 6 строчке. Также необходим метод, который может открывать и закрывать статью – создадим его на 9 строчке. В Article, передадим состояние и функцию открытия статьи – 20 строчка.

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

Пожалуйста загрузите исходный код урока отсюда.

Задание для самостоятельной работы.

Нужно создать миксин и декоратор для уже описанного нами функционала: отображение только одной открытой статьи, а также возможность закрытия всех статей и отображения только заголовков.
keep-calm-there-s-more-to-come

We are looking forward to meeting you on our website soshace.com

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

Уроки Express.js . Логгер, Конфигурация, Шаблонизация с EJS. Часть 2.

Favicon – это все connect Middleware, он смотрит, если url имеет вид favicon.ico, то он читает favicon и ...

3. Уроки Express.js. Шаблонизация с EJS: Layout, Block, Partials

В реальной жизни у нас обычно больше, чем один шаблон. Более того, если уж так ...

24.11.2016

Уроки Express.js. Основы и Middleware. Часть 2.

Всем привет! Давайте продолжим наш урок об основах Express и Middleware. Итог (добавим в ...

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy