Skip to main content

Що робить хук useSelector()?

Хук useSelector() - це один із двох головних хуків бібліотеки React-Redux (другий - useDispatch()), і він потрібен для того, щоб дістати дані з Redux-store всередині React-компонента.


Визначення

useSelector() - це хук, який дозволяє React-компоненту підписатися на Redux-store і отримувати потрібні дані зі стану (state).

Він замінює старий HOC connect().


Сигнатура

javascript
const result = useSelector(selectorFunction)
  • selectorFunction - це функція, яка приймає весь Redux-state і повертає тільки ту частину даних, яка потрібна компоненту.
  • result - це дані, які компонент буде використовувати.

Простий приклад

javascript
import { useSelector, useDispatch } from 'react-redux' function Counter() { const count = useSelector(state => state.counter.count) const dispatch = useDispatch() return ( <div> <p>Лічильник: {count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button> <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button> </div> ) }

Тут useSelector(state => state.counter.count):

  • підписує компонент на зміни поля state.counter.count;
  • повертає актуальне значення count;
  • якщо count змінився -> React автоматично перемалює компонент.

Як це працює під капотом

  1. При першому рендері useSelector():
  • викликає переданий селектор selector(state);
  • зберігає результат.
  1. Коли в Redux-store відбувається dispatch():
  • React-Redux порівнює старе і нове значення, яке повернув селектор.
  • Якщо дані змінилися (за ===), компонент перемальовується.
  • Якщо ні - компонент не ререндериться -> економія продуктивності.

Приклад з декількома селекторами

javascript
const user = useSelector(state => state.user) const todos = useSelector(state => state.todos)

Кожен виклик useSelector() підписується тільки на свою частину стану.


Просунуті прийоми

Мемоізація селектора

Якщо селектор робить обчислення, можна мемоізувати його за допомогою reselect:

javascript
import { createSelector } from 'reselect' const completedTodosSelector = createSelector( state => state.todos, todos => todos.filter(t => t.completed) ) const completed = useSelector(completedTodosSelector)

Користувацька функція порівняння

Можна передати другим аргументом функцію для тонкого налаштування того, як саме порівнювати результати (типово - строге порівняння ===):

javascript
const user = useSelector(state => state.user, (a, b) => a.id === b.id)

Що робить useSelector() всередині (у двох словах)

  • викликає store.subscribe() - щоб слухати оновлення;
  • викликає store.getState() - щоб отримувати актуальний стан;
  • викликає селектор при кожній зміні store;
  • якщо результат змінився - викликає setState() -> ререндер компонента.

Підсумок

Що робитьОпис
Читає дані зі storeДістає потрібний шматок стану
Стежить за змінамиАвтоматично підписується на оновлення
Оптимізує перерендериПеремальовує компонент тільки при реальних змінах
Замінює connect()Сучасний спосіб підключення Redux до React

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.