TGViewer
dev.easy dev.easy @dev_easy · 135 subscribers
Post #15 371
🎃 react-redux и connect-хелл

На днях разговаривая с коллегами и друзьями осознал что далеко не все понимают как работают connect и useSelector и почему даже с реселектом перфоманс может просесть.

Так вот, mapStateToProps из connect и селектор из useSelector вызываются при каждом изменении вашего стора, вообще при каждом изменении, без исключений. Если вы используете connect или useSelector только в рутовых компонентах (обычно самые верхние компоненты в дереве, например компоненты роутов) или модулях (компоненты который конектятся к стору но используется на странице всего несколько раз), то скорее всего у вас все ОК. Да будет гемор с проп-дрилингом (прокидывание пропсов в глубь дерева), но об этом ниже. Ну а если вы юзаете connect или useSelector везде где только можно, то могут быть проблемы с перфом.

Во первых - в достаточно больших проектах на одной странице может быть несколько тысяч компонентов которые используют коннект/селект хук, и все селекторы внутри этих компонентов будут вызываться при каждом изменении стора. Да, с использованием memo или connect, все компоненты перерисовываться не будут, только те, для которых данные реально поменялись, но это делает реакт, а не redux или reselct. Представьте что у вас реалтайм приложение, экшены приходят по сокетам, несколько(а может 10+) раз в секунду, так вот на каждый такой экшен все видимые селекторы (которые используется в отрендереных комонентах) будут запущены. А если реалтайм это не про меня, возразите вы, то вот пример с когда-то популярной либой redux-form , где на каждое нажатие клавише при вводе в инпут летит экшен в стор и опять эти тысячи селекторов будут запущены, на каждое нажатие клавиши, НА КАЖДОЕ КАРЛ...

Во вторых - connect, в отличает от useSelector, гарантирует что у родительских компонентов mapStateToProps будет вызван раньше чем у дочерних, это нужно что бы пофиксить "stale props" и "Zombie child" ([https://react-redux.js.org/api/hooks#stale-props-and-zombie-children](https://react-redux.js.org/api/hooks#stale-props-and-zombie-children)). Эта гарантия добавляет экстра логику и кучу вложенных провайдеров, что так-же влияет на перф при ооочень большой вложенности конектов. В добавок connect под капотом юзает PureComponnet и оптимизирует ререндеры, но во многих ситуациях это излишне. Например все с тем-же redux-form - зачем нам сравнивать пропсы, если мы и так знаем что компонент будет перерисован при каждом нажатии клавиши(читай изменении пропса).

Все это может казаться незначительным, но в больших проектах такие мелочи вытекают в реальные проблемы и приходится придумывать какие-то решение, а иногда и хаки, т.к. съехать с редакса не так-то просто 😢.

Одно из простых и довольно быстрых решений, которое так-же решает проблемы с проп-дрилингом - использовать контекст для всего, что меняется редко, но юзается часто. Я не говорю хранить значение только в контексте, можно использовать контекст как механизм доставки данных из редакса в глубь дерева. Например цветовая тема, или локаль браузера, или текущий юзер, все эти данные меняются очень редко, но могут использоваться сотнями компонентов. Если тянуть эти данные из редакса прямо в компонентах - будет connect-hell. Но можно создать отдельные контексты для темы, локали, и т.д., обернуть апку в эти контексты, пробросить им данные из редакса, а в компонентах юзать только контекст. Таким образом вместо сотен/тысяч конектов мы имеем только 1, там где данные тянуться из редакса и пробрасываются в контекст, а компоненты будут обновляться автоматически при изменении значений в контексте самим реактом.

Продолжение в первом коменте...
Читать в ноушен: https://bit.ly/3zdmFgL

#react #redux
  • 🔥 1
  • 💯 1
More from @dev_easy
  1. Nov 12, 2021🦾 local env на стиройдах Как я уже упоминал несколько раз, весь наш бэкенд построен на ми…
  2. Oct 25, 2021⚛️ неочевидный react Похоже, далеко не все понимают как работает React, в частности: конте…
  3. Oct 14, 2021🚐 лайфхаки ревью В стартапе где я работаю нет тестировщиков, от слова вообще. Мы, конечно…
  4. Oct 6, 2021🔫 самое коварное CSS свойство Пару недель назад наш дизайнер завел ишью, мол у него в хро…
  5. Sep 23, 2021🗽vite - будущее уже здесь Сегодня знаменательный день, мы переехали с webpack5 на vite. З…
  6. Aug 27, 2021🎹 Массивы и Таплы В TS/JS массивы можно разделить на 2 типа, обычные массивы и таплы (tup…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →