Useselector

Хук useSelector() — перерождение mapStateToProps из функции connect(). Разберём, как с помощью этого хука «вытащить» кусок состояния в компонент:


import { useSelector } from 'react-redux';

function App(props) {
    // Используем хук для получения данных из хранилища
    // По умолчанию из замыкания есть доступ к собственным пропсам компонента
    const { todos, theme, user } = useSelector(store => ({
            todos: store.todos,
            theme: props.theme ? props.theme : store.appearance.theme,
            user: store.account.userData
    }))
    
  // ...
}

// Больше не нужен connect
export default App;
 

В этом примере мы использовали хук useSelector для чтения данных из хранилища. Такой компонент можно без труда перемещать вверх и вниз в иерархии компонентов и не волноваться за дополнительные зависимости между компонентами и определённую структуру. Такой компонент — самодостаточная «деталь», которую можно использовать в любом месте приложения.

Первый аргумент хука useSelector — функция вида (store) => store. Не возвращайте всё хранилище целиком, это может сильно ухудшить производительность, ведь любое изменение данных в хранилище будет вызывать дополнительный рендеринг. Старайтесь вычленять из хранилища только те значения, которые важны для конкретного компонента. То же самое справедливо и для функции mapStateToProps.

Второй аргумент хука — функция-компаратор, иначе — функция, которая проверяет равенство двух объектов. Это опциональный аргумент. Если ваше приложение зависит от фактического изменения (или неизменности) конкретных ключей из хранилища, вы можете воспользоваться этим аргументом:

import { useSelector, shallowEqual } from 'react-redux';

function App(props) {
    // Используем хук для получения данных из хранилища
    // По умолчанию из замыкания есть доступ к собственным пропсам компонента 
    const { todos, theme, user } = useSelector(store => ({
            todos: store.todos,
            theme: props.theme ? props.theme : store.appearance.theme,
            user: store.account.userData
    // Передаём функцию-компаратор вторым аргументом
    }), shallowEqual)
    
  // ...
}

// Больше не нужен connect
export default App;

В этом случае мы использовали функцию shallowEqual, которая идёт в пакете react-redux. С её помощью мы реализовали неглубокое сравнивание двух объектов. Если потребуется, вы можете написать собственную реализацию функции-компаратора. Для этого используйте такую сигнатуру функции: (objA, objB) => boolean.

#react