Вот мы построили приложение на React с глобальным состоянием в хранилище Redux. Но пока есть неудобства. Загрузка лотов производится даже когда мы не выводим их на странице, вхолостую занимая ресурсы браузера. И ещё использование внешнего хранилища порой может быть лишним.
Сегодня рассмотрим варианты хранения локального состояния внутри компонента. Код побочных эффектов сделаем выполняемым только при необходимости. И рассмотрим внутреннюю работу хуков React для использования побочных эффектов в функциональных компонентах:
- 00:00:48 Постановка задачи
- 00:02:20 Глобальное и локальное состояния
- 00:04:10 Классовый компонент
- 00:05:33 Ручное использование полей
- 00:09:15 Локальное состояние в Component
- 00:11:18 Создание таймера
- 00:13:37 Вынесение контейнерного компонента
- 00:16:09 Плюсы и минусы
- 00:17:49 Мотивация введения хуков
- 00:19:45 Состояние через хук useState
- 00:21:53 Устройство и работа хуков
- 00:26:08 Изменение локального состояния
- 00:26:55 Компонент React.Fragment
- 00:29:49 Побочные эффекты в useEffect
- 00:36:48 Перенос загрузки лотов
- 00:39:05 Уточнение зависимости
- 00:40:04 Добавление флага загрузки
- 00:42:16 Вынесение подписки на цены
- 00:44:28 Отписка от уведомлений
- 00:47:57 Вынесение контейнеров
- 00:49:20 Многошаговый процесс подгрузки
- 00:55:52 Локальное хранение лотов
- 00:57:17 Атомарность изменения состояния
- 00:59:49 Возврат процедур в компонент
- 01:02:10 Сравнение подходов
- 01:03:31 Замена Redux на useReducer
- 01:05:32 Обзор результата
- 01:06:47 Комбинация подходов
- 01:09:09 Обзор результата
А в следующем эпизоде рассмотрим маршрутизацию через History API браузера.
Скрытый контент (код, слайды, ...) для подписчиков.
Открыть →Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Супер
Спасибо.
Спасибо! Вообще получается что классы или функциональные компоненты это разные парадигмы разработки на Реакте, и мне кажется идет уход от классов да и от Редакса. Многие вещи решаются с помощью кастомных хуков, например та же авторизация. Вот тут много примеров есть https://usehooks.com, кому интересно. Т.е глобальные данные упаковываются либо в оборачивающий компонент, ну или в компонент высшего порядка. Но конечно, это вопрос личных предпочтений, как писать. Но вообще это чем то напомнило мидлвары в бэкенде.
Да, изначально были классы с методами жизненного цикла, но сейчас рекомендуют переходить на более простые функции с хуками.
А по хранению данных часто используют локальное состояние и контексты. Но многие крупные проекты всё равно делают со внешними хранилищами если им требуется выделенная централизованная модель данных.
В этом эпизоде заметно, что простой виджет Clock спокойно перешёл на локальное состояние. Но как только мы всё состояние с лотами и экшены со stream и api перенесли внутрь Lots этот компонент сразу стал монструозным и почти нетестируемым. Так что не всегда очевидно что будет удобнее.
Как по ощущениям, функциональные компоненты выглядят громоздко и не понятно в отличии от классов. Зачем это нужно было делать, какие насущные вопросы решал фейсбук....
То есть этот компонент:
Выглядит более громоздким, чем этот?
В классах кода больше, но и ясности больше что происходит
Но если знать, как работают хуки, то и в функциональном компоненте все предельно ясно
Дмитрий, спасибо за уроки, подскажите что за шрифт в самой программе idea?
Интерфейс шрифтом Tahoma
В редакторе DejaVu Sans Mono
Благодарю
А если вот будет отдельная страница с лотом, куда нужно будет вывести данные о лоте, то как это правильно сделать? Получается, будет компонент LotPage и он будет с адресной строки брать айди лота? А потом нужно сделать запрос на сервер чтобы получить этот лот, но где именно мы будем это делать, это же вроде как не экшен (в плане что вместе с экшенами мы его не поместим), состояние он никак не меняет, но запрос асинхронный? Плюс что если загрузка лота будет тоже такая продвинутая, как и у лотов?
Я думал что можно этот запрос сделать эффектом, вынести в контейнерный компонент с локальным состояниям где будет также вся эта продвинутая загрузка, но а что если я захочу протестировать этот эффект, вынести его куда-то и куда тогда? Так же каким образом этот контейнерный компонент будет получать доступ к объекту api, через пропсы его передавать?
Как бы вы это сделали?
Да, LotPage в плане состояния и загрузки будет работать абсолютно также как Lots. Он будет брать id из маршрутизатора и у себя подгружать текущий лот.
Если с api всё будет в одном компоненте, то тогда со всеми хуками нужно будет тестировать весь компонент через React Testing Library. И там подменять переменную
global.fetch
или модульapi
на заглушку, как мы делали в эпизоде про регистрацию.спасибо
Несколько вопросов по реализации функции resolveDispatcher() (Тайминг: 22:16) (Скриншот)
Интересно, для чего поступили именно так:
1) Зачем такая "сложная" проверка в if с использованием инверсии? Короче, читабельный же:
if (dispatcher === null)
.2) Зачем выброс исключения обернули в отдельную область видимости
{}
?3) Почему используют var, а не let? Для совместимости?
Да, весьма странный подход. Надо спросить у авторов этого кода.
Спасибо! Не понимаю, а чем плохи классы-компоненты? Все ради экономии пары строк кода и ТОЛЬКО поэтому или есть более весомые аргументы против? А чем плох redux?)
Да, для экономии десятка строк кода.
Глобальный state со всеми данными на весь проект плох тем, что облегчает нарушение дисциплины, когда какой угодно программист в любом своём компоненте может обратиться к чему угодно. Это может привести к запутанному коду, когда не понятно, кто из тысячи компонентов что использует из тысяч полей. В отличие от этого локальное состояние заставляет программировать более аккуратно и все передачи значений наружу производить только когда это действительно понадобится.
А конкретно сам Redux многим неудобен по причине неэкономии строк кода. Что для любого изменения какого-то поля приходится прописывать кучи кода в виде действия, фабрики и ветки в редьюсере. Вместо него часто выбирают Mobx, где столько кода не нужно.
Или войти через: