Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить хук useSelector()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useSelector()`** - це один із двох головних хуків бібліотеки **React-Redux** (другий - `useDispatch()`), який дозволяє React-компоненту підписатися на Redux-store і отримувати потрібні дані зі стану (state). **Ключове:** він замінює старий HOC `connect()` і перемальовує компонент тільки тоді, коли результат селектора справді змінився.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняХук `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)`; - зберігає результат. 2. Коли в 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 |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.