Всем привет, данная статья направлена на то, чтобы добавить понимания при использовании хука useSelector в разработке. Надеюсь, у меня получилось ниже раскрыть какую-то часть информации, которая поможет разработчикам, которые раньше не знали данной информации. Все, кто использует Redux в React так или иначе знают, что useSelector является одним из основных хуков для получения данных из стора Redux в компонентах и кастомных хуках React. При этом часть разработчиков даже не подозревает о возможных проблемах, которые могут возникать в работе, если не обдумывать некоторые моменты разработки, используя данный хук.  Речь пойдет о проблемах, которые могут возникать при деструктуризации данных из стора с использованием useSelector. Как мы знаем, при использовании useSelector мы передаем в него функцию-селектор, с помощью которой и выбираем нужные данные из хранилища Redux. При использовании деструктуризации мы извлекаем конкретные свойства из объекта состояния Redux. Но мы не должны забывать о главной проблеме такого подхода - если изменяется любое свойство объекта, который мы деструктуризируем (даже если это свойство не было присвоено переменной во время деструктуризации) происходят дополнительные перерисовки компонентов, даже если свойство менялось совсем в другом компоненте.  Попробуем кратко объяснить, почему так происходит. Когда мы извлекаем часть объекта из стора с использованием деструктуризации, мы создаем новый объект, который имеет ссылку отличную от деструктуризируемого объекта. При этом, когда меняются свойства объекта в сторе происходит создание нового объекта (новой ссылки) в деструктуризации, что и приводит к дополнительному перерендеру компонента. Одним из основных способов избежать данной проблемы является прямое присваивание свойств из стора переменным вместо использования деструктуризации. Добрые люди в интернете написали небольшой код, который демонстрирует поведение работы при обоих случаях. Прикладываю песочницу, чтобы все могли посмотреть и поиграться с ним. https://codesandbox.io/s/redux-useselector-object-destructuring-example-6up7h Рассмотрим, что же происходит в данном коде. Изначально у нас есть три компонента, которые рендерятся при загрузке страницы. В каждом из этих компонентов присутствует получение данных из стора разным способом. При этом в сторе лежит два значения: firstCounter и secondCounter.  Мы видим, что в первом и третьем компоненте используется деструктуризация двумя способами, а во втором компоненте происходит прямое присваивание. При увеличении firstCounter можно заметить, что все работает так, как нам и нужно - происходит увеличение значения на 1 и при этом происходит по 1 рендеру в каждом компоненте.  Теперь попробуем увеличить secondCounter. И что же мы видим? Увеличение secondCounter привело к дополнительному рендеру первого и третьего компонента, хотя он там даже не используется. Во втором же компоненте количество рендеров осталось без изменений, из чего можно сделать вывод, что прямое присваивание устраняет данную проблему.  Действительно, есть еще несколько способов, которые имеют место быть. 1) Можно использовать функцию shallowEqual из пакета react-redux для сравнения объектов из стора. Она передается вторым аргументом в useSelector. Попробуем добавить эту функцию в выше приведенный код. В данном случае действительно дополнительные рендеры были устранены. Но вот в этом случае дополнительные рендеры не были устранены. Это связано с тем, что в случае с третьим компонентом мы вытаскиваем непосредственно значение firstCounter из стора и кладем его в объект под ключ firstCounter, после чего и происходит деструктуризация. И, если firstCounter не меняется в сторе, то не меняется и ссылка на него. Во втором же случае shallowEqual сравнивает ссылки объекта counters и при изменении secondCounter ссылка все равно меняется и происходит дополнительный рендер. P.S. поправьте меня, если это не совсем так 2) Еще один из способов - это использование библиотеки reselect. В данном случае значение будет изменяться только в том случае, если оно было изменено в сторе. Приведу топорный рабочий пример, возможно, есть более удобный и рациональный способ использования, который я бы тоже был бы рад увидеть. Из приведенного выше понятно, что использование деструктуризации - не самый лучший способ получения данных из стора с использованием useSelector, так как это приводит к лишним и, вряд-ли нужным, рендерам. Как по мне, самый удобный способ - это просто присваивать напрямую. Во всех приведенных  примерах видно, что происходит добавление лишнего кода, которого не избежать, но первый способ выглядит более читаемым и без дополнительных заморочек. Но, как говориться, на вкус и цвет... Отходя от выше написанного можно добавить, что при использовании прямого присваивания лучше всего выносить все функции, передаваемые в useSelector, в отдельный файл и дальше уже их использовать. Это может повысить читаемость, уменьшит постоянное дублирование кода и, в конце концов, если изменится название переменной в сторе - ее надо будет поменять только в одном месте, а не бегать по всем файлам в поисках useSelector для изменений имени.   Frontend-разработчик