SIGN IN

Уроки React. Урок 7

logo_og
Всем привет! Сегодня у нас будет довольно важный урок, мы все ближе и ближе подбираемся к Redux, но для начала пробежимся по нашему домашнему заданию, оно было довольно простым, но все таки для проверки покажу как добавить наш календарь.

Установим наш модуль:

npm install react-day-picker —s

Проверим, что в нашем package.json появилась запись об этом:

В ArticleList сделаем import самого Day-picker:

State изменим следующим образом:

В наш div добавим к нашему select новый модуль:

А ниже опишем логику работы компонента:

Теперь у нас есть функционирующий календарь и при выборе периода он отображает дату рядом с нашим заголовком “Article list”.

Обратите внимание, что наш компонент ArticleList разрастается, это довольно плохо. У нас появилось довольно много кода –  это верный знак к тому чтобы вынести наши select, day-picker вместе с их логикой в отдельные компоненты, скажем в Filters. Проблема в том что если мы сделаем это прямо сейчас то у нас будет много проблем с передачей значений. Нам хотелось бы чтобы наши компоненты были атомарными, выполняющими отдельные узкопрофильные задачи. Можно сказать что наш компонент стал взрослым и нам пора задуматься о бизнес-логике, и добавить Redux или Flux.

Вспомним о том как работает React и его Virtual DOM,  в картину его с трудом вписывается MVC подход и т.п., тем более в больших приложениях понять как работает тот или иной компонент достаточно сложно, так как приходиться держать очень много всего в голове (касаемо того как работает приложение), вспомните о Two-way data binding и прочих особенностях Angular и Ember.
Вместо этого команда React предложило другое решение по построении логики – Unidirectional data flow.  Рассмотрим каким образом работает Redux.

react-redux-introduction-33-638

У нас есть Store – они отвечают за хранение данных, именно из них View читает данные и отображает их.

Action – это events, объекты которые описывают то, что будет происходить. Они создаются для описания коммуникаций с User (клик мышкой, нажатие клавиши) или API.

Dispatcher – Actions попадают в dispatcher, он разбрасывает их по Stores, те в свою очередь реагируют, обрабатываю Actions. Например пришел action deleteArticel, store понимает, что нужно пойти и удалить какую-то статью, и оповещает View о том, что изменилось, View запрашивает все данные которые ей нужны чтобы перестроить UI.

Несколько слов об отличии Flux от Redux:

1. Во-первых Redux больше сосредоточен на концепциях  функционального программирования, и все элементы Unidirectional data flow значительно сильные разделены между собой. Скажем Store это Immutubable object который отвечает исключительно за сохранение состояния.

2. В Redux отказались от внешнего Dispatcher’а который связывал все вместе. Также у нас один store на всех, а dispatcher спрятан внутри, для работы с ним разработчикам предоставлен  API.

Так как у нас один store у нас один метод подписки на него. Flux очень гибкий и имеет много store – что скорее всего будет мешать при разработке.

3. Action-creators в Redux это просто чистые функции  которые возвращают вам объект, с какими либо данными, которые вместе с этим action.

Диспетчер здесь отсутствует.

4. Stores => Reducers, это механизм перехода между состояниями. Reducers это тоже чистые функции. Это функция которая знает начальное состояние, получив какой то action должна перейти в другое состояние. Они не меняют старое, а возвращают новое:

Давайте прежде чем делать что-либо сложное сделаем простой Counter с  Redux. Будем отображать на странице число и увеличивать его значение при нажатии на кнопку.

Зайдем в app.js и закомментируем наш Articlelist и заведем компонент Counter в папке components:

Также сделаем возможность инкремента по клику. Далее вернемся в app.js и сделаем импорт компонента:

А также добавим:

Теперь установим Redux в console:

npm i redux –S

Теперь count мы будем хранить в store а не передавать его вручную.

Для этого конечно же создадим Store. Создайте директорию с таким названием в src. Там создадим файл index.js. Для начала обратимся к документации Redux.

Прежде чем говорить про store, прочтите главу createStore. Все ваши данные будут жить в нем. Создается он с помощью функции:

createStore(reducer, [preloadedState], [enhancer])

с одним обязательным аргументом – reducer.

Теперь создадим наш store:

И сюда же будем передавать наш reducer, который мы создадим отдельно. Создайте папку reducer в src, и соответствующий файл index.js внутри. Как мы уже говорили reducer – это обычная функция, которая принимает текущее состояние и action, и возвращает новое состояние. Так же добавим window, чтобы можно было отслеживать  текущее состояний.

Пишем в нашем reducer:

не забудем сделать import в app.js

Обратимся к документации. а именно к методам store. Нас будут интересовать 3 из них:

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

Чтобы что то изменить в Store мы должны вызвать action creater с помощью второй метод dispatch. Попробуйте его в console браузера:
store.dispatch({type: ‘INCREMENT’})

Теперь состояние измениться на 1.

Теперь поработаем с отображением. В app.js добавим storeGetState, также мы хотим подписаться на изменения store и передавать их в counter, расстроим еще один способ:

Теперь при каждом обновлении store автоматически обновляется наше число.

Теперь нашу ссылку нужно подружить с action creater.

Создадим файл  constants в src в котором будем хранить словарь с доступными типами actions :

В reducer добавим, и кое что поправим:

Заведем директорию AC, а в ней файл counter.js:

В app.js сделаем import, а также dispatch и передадим его в наш counter как props:

counter.js измениться следующим образом:

count: PropTypes.number, increment: PropTypes.func

this.props.increment()

Вот таким способом, мы закончили простую работу с данными. Мы по клику на ссылку вызываем метод, который пришел к нам через props, этот метод вызывает store.dispatch, при этом оборачивая в него наш простой action creater, который просто создает этот объект, который описывает наш action (в counter.js –  type: INCREMENT). Далее наш store, берет и вызывает свой reducer, передавая в него текущее состояние и action. Этот reducer вернет уже новое состояние, store запишет это новое состояние себе и вызовет callback который мы передали в store.subscribe. Этот callback заново вызовет метод render и перестроит заново наш компонент, и мы увидим число на один больше. Так выглядит простой Redux цикл, построенный с нуля.

Код урока находится здесь.

Снимок

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 correct name
Please enter correct email
Looks good!

Related articles

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

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

Programming

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

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

Programming
24.11.2016

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

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

Programming

4 comments

Pavel Bragin November 28, 2018 at 1:33 pm
0

здравствуйте автор! большое спасибо вам за труд! но есть некоторые недочеты и опечатки в кодах(различаются коды в материалах сайта и на GITe). а теперь вот в этом разборе домашнего задания ошибка при объявлении ф-ии handleDayClick. с заданными аргументами код не работает, нужно оставить один аргумент day. поправьте пожалуйста…

 
Pavel Bragin November 28, 2018 at 3:34 pm
0

Спасибо за комментарий! У нас все работает, вот посмотрите:
http://joxi.ru/5md7jWaSkz4xBr
Причина в версии Day-Picker:
http://joxi.ru/E2pdRkNh9NB762
C 5ой версии поменялся порядок объявления аргументов. Мы работали тогда с версией 2.5. Рекомендую поставить старую версию чтобы корректно работали остальные уроки.

Pavel Bragin November 28, 2018 at 1:33 pm
0

Здравствуйте, Автор. Подскажите, пожалуйста, для чего вызов метода dispatch необходимо оборачивать в обертку в виде функции wrappedIncrement?

 
Pavel Bragin November 28, 2018 at 1:33 pm
0

Если мы передадим store dispatch, то мы его просто вызовем и передадим результат. А в props increment мы должны передать функцию, потому что хотим дать возможность Counter’у делать икремент с помощью this.props.increment()

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