Що робить хук useSelector()?
Хук useSelector() - це один із двох головних хуків бібліотеки React-Redux (другий - useDispatch()),
і він потрібен для того, щоб дістати дані з Redux-store всередині React-компонента.
Визначення
useSelector()- це хук, який дозволяє React-компоненту підписатися на Redux-store і отримувати потрібні дані зі стану (state).
Він замінює старий HOC connect().
Сигнатура
const result = useSelector(selectorFunction)selectorFunction- це функція, яка приймає весь Redux-state і повертає тільки ту частину даних, яка потрібна компоненту.result- це дані, які компонент буде використовувати.
Простий приклад
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 автоматично перемалює компонент.
Як це працює під капотом
- При першому рендері
useSelector():
- викликає переданий селектор
selector(state); - зберігає результат.
- Коли в Redux-store відбувається
dispatch():
- React-Redux порівнює старе і нове значення, яке повернув селектор.
- Якщо дані змінилися (за
===), компонент перемальовується. - Якщо ні - компонент не ререндериться -> економія продуктивності.
Приклад з декількома селекторами
const user = useSelector(state => state.user)
const todos = useSelector(state => state.todos)Кожен виклик useSelector() підписується тільки на свою частину стану.
Просунуті прийоми
Мемоізація селектора
Якщо селектор робить обчислення, можна мемоізувати його за допомогою reselect:
import { createSelector } from 'reselect'
const completedTodosSelector = createSelector(
state => state.todos,
todos => todos.filter(t => t.completed)
)
const completed = useSelector(completedTodosSelector)Користувацька функція порівняння
Можна передати другим аргументом функцію для тонкого налаштування того,
як саме порівнювати результати (типово - строге порівняння ===):
const user = useSelector(state => state.user, (a, b) => a.id === b.id)Що робить useSelector() всередині (у двох словах)
- викликає
store.subscribe()- щоб слухати оновлення; - викликає
store.getState()- щоб отримувати актуальний стан; - викликає селектор при кожній зміні store;
- якщо результат змінився - викликає
setState()-> ререндер компонента.
Підсумок
| Що робить | Опис |
|---|---|
| Читає дані зі store | Дістає потрібний шматок стану |
| Стежить за змінами | Автоматично підписується на оновлення |
| Оптимізує перерендери | Перемальовує компонент тільки при реальних змінах |
| Замінює connect() | Сучасний спосіб підключення Redux до React |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.