🏠Домашнее задание
⚡ 1) Зачистить стейт при вылогинивании
Если вылогиниться из приложения, то таски и тудулисты, которые находятся в стейте не зачищаются. И это не есть хорошо. В данном видео описана проблема и ее реализация на redux. Ваша задача сделать это на redux toolkit
⚡2) Работа с селекторами
Рефакторим все селекторы в приложении согласно auth.selectors.ts

В данном видео (запись с урока) максимально подробно рассказываю про работу с селекторами
-----------------------------------------------------------------------------------------------------
⚡1) Intro
Давайте зайдем в компонент App.tsx и посмотрим как мы достаем данные из стейта
Казалось бы и что тут рассказывать, но на самом деле есть нюансы которые нужно знать
⚡2) useAppSelector
⚡2.1) Вводная часть
Давайте перепишем доставание isLoading вот так
Я довольно часто вижу такую запись. Почему так студенты любят писать. Допустим нам из app стейта нужно достать 3 значения (isLoading, isAppInitialized, unHandleActions)
И теперь сравним 2 варианта
Сравнивая 1 и 2 вариант, очевидно что в 1 случае кода писать меньше, именно поэтому так и любят писать.
Теперь проверьте, поменялось ли что-нибудь или нет ?
Ответ: Нет, ничего не поменялось. Значит получается без разницы как писать? А вот здесь ответ нет, разница существенная.
⚡ 2.2) Начнем со 2 варианта Вот такой у нас будет стартовый код
Вот, что мы увидим в консоли

isLoading изменил свое состояние, соответственно компонент App перерисовался. Все логично, все хорошо.
теперь давайте в useEffect через 3 секунды будем менять error (вмеcто
isLoading)

⚡ 2.3) Теперь все тоже самое проделаем для 1 варианта
1) Для первого варианта, когда меняем крутилку ничего не поменялось
2) Но когда мы меняем ошибку, то получим следующий итог

В App.tsx мы не достаем error, но она все равно перерисовывается 🤯🤯🤯
Берем максимально точечно данные из стейта
Никогда не используем деструктуризация в селекторах (Можно этим правилом пренебречь в том случае, если уверены, что все свойства стейта используются в компоненте)
⚡3) Selector
Опять возвращаемcя к нашему исходному селектору
⚡3.1) Как правило в разных компонентах нам нужно доставать одинаковые данные из стейта. Т.е. Код я указал выше может использовался в 10 компонентах.
А теперь представьте что у нас в приложении мы решели заменить свойство isLoading на loadingStatus. К чему это приведет?
Это приведет к тому, что нам нужно идти в 10 компонент и менять эти свойства, что не очень приятно.
⚡3.2) При каждом рендере - новая функция. Cелектор будет вызываться при каждом рендере, а не только когда обновились данные в сторе.
⚡3.3) Логика получения данных из структуры стора находится внутри компонента. Но зачем компоненту знать об этом?
По этим причинам селекторы выносят в отдельные функции, которые в принципе так и называют.
Создадим файл app.selector.ts и вынесем туда кода доставания значения из стейта

Функции селекторы называют по разному. Встречал следующие варианты:
selectIsLoading
isLoadingSelector
иногда вообще в названии не указывают select (selector) и группируют все селекторы в один объект (namespace). Я так не делал никогда : )
Все селекторы выносим в файл с селекторами
Селекторы кладем в отдельные файлы соответствующие фиче.
⚡4) Reselect
Говоря про селекторы нельзя не упомянуть про createSelector
⚡4.1) Теория
Селекторы можно разделить на 2 типа
простые (обычные) селекторы - это селекторы которые просто достают данные из стейта
Такие селекторы стоит использовать всегда, когда мы напрямую ссылаемся на данные из стора. Даже если возвращаемое значение является объектом, не стоит беспокоиться - мы лишь возвращаем ссылку на уже существующий объект, который находится в стейте, так что ни к каким проблемам это не приведет.
сложные селекторы, это селекторы в которых мы делаем сортировку / фильтрацию или сложные вычисления
⚡4.2) Практика
Задача Отображать только те колоды у которых в имени содержится буква f.
в проекте с карточками поиск, фильтрации, сортировка реализована на сервере, но ради примера давайте будем с сервера запрашивать 100 колод и фильтровать их по имени локально.
1) Захаркодим запрос за 100 колодами
2) Вынесем получение колод в селектор
3) Теперь сделаем сложный селектор в котором собственно и будем осуществлять логику по фильтрации
Теперь воспользуйтесь данным селектором в Packs.tsx. Попробуйте фильтровать по разным буквам и убедитесь, что все отрабатывает верно 👍
4) Для того, чтобы понять что собственно не так, давайте компонент Counter (мог бы быть абсолютно любой компонент в котором используется useSelector) уберем из роутинга и вставим на одном уровне с App
5) Напишем console.log('render ${component}') в Packs.tsx и Counter.tsx
И теперь измените меняйте значение Counter

Мы меняем значение счетчика, который вообще никоим боком не связан с колодами, но мы видим как она перерисовывается 🤯🤯🤯.
6) И вот чтобы избежать вот такого поведения нам и нужен createSelector
По итогу получим вот такой результат 🚀

🔗 Примеры работы с useSelector из документации
☝ Вывод по использованию createSelect такой
1) Используйте мемоизированные селекторы когда:
В селекторе есть тяжелые вычисления (фильтрация, сортировка, сложное преобразование данных, и так далее)
Результатом вызова селектора является объект. Ну и конечно же, это касается массивов и различных структур вроде Set и Map, так как они тоже являются объектами.
2) Есть мнение о том чтобы без анализа селектора всегда использовать reselect
Last updated