Уроки React. Урок 12.

react_12
Всем привет! Сейчас мы пробежимся по нашему домашнему заданию, а также дадим важные комментарии , которые помогут Вам в дальнейшей работе с React.  Для удобства Вам понабиться видеть перед собой код, поэтому перейдите на нужный commit и мы продолжим. Начнем с connect.connect нужен нам, чтобы обратиться к store. Добавим небольшую ремарку, что если Вы можете передать данные используя обычные props – передавайте. Например в containers/Articles.js  мы обращаемся к store чтобы из его state достать необходимые нам статьи:


А в Article/index.js мы, например,  conncet не используем. Компонент render‘иться сам по себе.  А в случае с  containers/CommentList.js мы опять делаем этот компонент “умным”, используя connect, так как в противном случае мы просто до него не сможем добраться . У нас нет этих комментариев в state, они хранятся  в storeи до них нужно как-то добраться, поэтому единственным правильным способом является использование  conncet .


Есть способ достать комментарии с помощью рукописного helper прямо из статьи, к примеру в методе render нашего CommentList.js. Делая это мы получаем не чистую функцию render и у нас появляется риск попасть в разнообразные неприятные ситуации, к примеру, когда вы делаете action , который обновляет комментарии, но при этом затрагивает статьи,  в результате –  этот компонент вообще не обновиться. Это происходит потому, что единственное обновление будет происходить на самом верхнем уровне, и оно будет связано с обновлением отфильтрованных статей в containers.js/Articles.js .


Redux проверит, совпадение списка отфильтрованных статей с предыдущим и  сделает вывод, что ничего обновлять не надо. Поэтому  connect мы добавляем в том случае, когда нам нужно обратиться за данными которых у нас сейчас нету. Мы стоим перед выбором: взять эти данные где-то на верхнем уровне или добавить connect уровнем ниже – это вопрос баланса который тяжело объяснить, т.к. в React нет какой-то логической формулы по этому вопросу.

Детально на выполнении домашнего задания мы останавливаться не будем, вы можете посмотреть пример выполнения в репозитории. Сейчас мы с Вами остановимся только на некоторых аспектах выполнения этой задачи, поэтому перейдите на нужный commit по ссылке сверху и мы пойдем дальше.

Как мы работаем с формами? Посмотрим на файл components/NewCommentForm.js . В state мы храним значения для наших inputsв данном случае это user и text.


Далее мы передаем значения из state в inputs,


и на событии onChangeмы передаем callback , который умеет менять это значение, в нашем примере это делается вот таким образом:


Далее мы легко можем обнулить эти данные, просто вызвав setState с пустыми строками, когда комментарии добавлены и у нас будут пустые inputs:


Теперь несколько слов о middleware. Их нужно писать таким образом чтобы было легко переиспользовать их в будущем. Потому что это такая часть архитектуры приложения, через которое будет происходить все взаимодействие. Каждый Ваш action будет проходить через эту middleware с того момента как вы ее подключили. Поэтому хорошо бы использовать ее много раз, а не для одного конкретного случая. Например, не стоит писать middleware для добавления id комментариев. Middleware для добавления случайного id может выглядеть так:


Вся прелесть React+Redux в его прозрачности, весь этот One-way data flow прекрасен тем что вы всегда знаете поэтапно, что у Вас происходит.  Вы знаете что в тот момент как только произошел submit на добавление комментариев они пошли у нас в Action creator, далее они попали в цепочку Ваших middleware и в каждой из них у Вас произошли очевидные изменения, в одной у Вас добавиться id , потом это все залоггируется (через logger.js ), потом это передастся в reducer там также только чистые функции, поэтому Вам будет легко контролировать процесс.  Потом все это приведет к обновлению Вашего DOM. Поэтому для debuggingВам просто необходимо проверить каждый из шагов. Если же добавлять middleware  для разных, но по сути однотипных  actions то в дальнейшем отследить процесс будет очень тяжело. Делайте middleware  более прозрачным способом.

Вернемся к нашему middleware . Мы с Вами в AC/comments.jsдобавляем флажок – withRandomIdпотом в middleware  мы проверяем, если у нас есть этот флажок мы добавляем случайный id и пускаем этот action дальше. Потом в reducer/articles.js мы достаем этот случайный id прямо из action :


и работаем с ним:


И последнее. Взгляните на reducer/articles.jsа именно на Record :


Это у нас immutable структура. Если с примитивами Вы ничего не сделаете, то вот с comments можете. Например используя push для comments вы  мутируете их, используя этот метод т.к. это простой массив. Этим действием вы теряете все то, что дают immutable структуры. Вы меняете что то внутри, а Immutable.js думает, что на самом деле ничего не поменялось.  Т.е. здесь у нас вместо concat делается push :


в результате ничего не возвращается. Сами данные изменились, но ничего не произойдет и в return все останется также.

Также несколько слов о вреде преждевременной оптимизации. Дело в том, что еще в прошлых уроках в containers/CommentList.js 
мы с Вами использовали много lifecycle hooks и в том числе shouldComponentUpdate() – он проверял, если isOpen меняется, то мы обновляем этот  CommentListесли isOpen не меняется, то мы явно говорим React не перестраивать  компонент. Это оптимизация для того чтобы не делать render компонента лишний раз, но это довольно опасная штука, не следует ее делать на каждом шагу.
Мы с Вами писали shouldComponentUpdate()и проверяли меняется isOpen или нет. На тот момент это была прекрасная оптимизация, так как когда у нас менялось что-либо не затрагивающие CommentList который умел только открываться и закрываться нас это не волновало. Но приложение усложнилось, к компоненту добавляется дополнительная логика и в результате если мы добавим shouldComponentUpdate снова:


комментарии добавляться не будут пока мы не будем закрывать/открывать комментарии. Почему так происходит? Из-за преждевременной оптимизации. Комментарии меняются, а isOpen нет. В результате компонент не перестраивается, т.к. его “больше интересует” isOpen . Поэтому будьте внимательны и используйте это только там где это реально нужно.

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

see-you-soon

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. Итог (добавим в ...

No comments yet

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