Reselect
— это библиотека для создания мемоизированных селекторов, используемых с Redux. Она помогает улучшить производительность, предотвращая ненужные перерасчеты данных в ваших компонентах. Селекторы — это функции, которые извлекают определенные части состояния из хранилища Redux и могут выполнять вычисления на основе этого состояния.
Установка
npm install reselect
Основные концепции
Селекторы — это функции, которые получают состояние хранилища Redux и возвращают данные. Они могут быть простыми или сложными, выполняющими вычисления на основе состояния. Reselect позволяет создавать мемоизированные селекторы, которые кэшируют результаты вычислений и предотвращают ненужные перерасчеты.
Простой селектор
Создание простого селектора без мемоизации:
const getTodos = (state) => state.todos;
Этот селектор просто возвращает список задач из состояния.
Мемоизированный селектор
Создание мемоизированного селектора с использованием createSelector
из библиотеки Reselect:
import { createSelector } from 'reselect';
const getTodos = (state) => state.todos;
const getCompletedTodos = createSelector(
[getTodos],
(todos) => todos.filter(todo => todo.completed)
);
В этом примере getCompletedTodos
— это мемоизированный селектор, который фильтрует завершенные задачи. Он будет пересчитываться только тогда, когда изменится список задач.
Примеры использования
Пример с несколькими селекторами
Рассмотрим более сложный пример, где мы используем несколько селекторов для вычисления данных:
import { createSelector } from 'reselect';
// Простой селектор для получения списка задач
const getTodos = (state) => state.todos;
// Простой селектор для получения фильтра задач
const getFilter = (state) => state.filter;
// Мемоизированный селектор для получения списка завершенных задач
const getCompletedTodos = createSelector(
[getTodos],
(todos) => todos.filter(todo => todo.completed)
);
// Мемоизированный селектор для получения отфильтрованных задач
const getVisibleTodos = createSelector(
[getTodos, getFilter],
(todos, filter) => {
switch (filter) {
case 'SHOW_COMPLETED':
return todos.filter(todo => todo.completed);
case 'SHOW_ACTIVE':
return todos.filter(todo => !todo.completed);
default:
return todos;
}
}
);
В этом примере мы используем два простых селектора getTodos
и getFilter
для получения данных из состояния. Затем мы создаем два мемоизированных селектора getCompletedTodos
и getVisibleTodos
, которые вычисляют списки задач на основе состояния и фильтров.
Использование селекторов в компонентах
Теперь рассмотрим, как использовать селекторы в компонентах React с Redux:
import React from 'react';
import { useSelector } from 'react-redux';
import { getVisibleTodos } from './selectors';
const TodoList = () => {
const todos = useSelector(getVisibleTodos);
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
};
export default TodoList;
Здесь мы используем хук useSelector
для получения данных из состояния с помощью мемоизированного селектора getVisibleTodos
. Компонент TodoList
рендерит список задач на основе фильтров.
Селекторы с параметрами
Селекторы также могут принимать параметры. Рассмотрим пример:
import { createSelector } from 'reselect';
const getTodos = (state) => state.todos;
const getTodoById = (state, todoId) => todoId;
const makeGetTodoById = () => {
return createSelector(
[getTodos, getTodoById],
(todos, todoId) => todos.find(todo => todo.id === todoId)
);
};
В этом примере makeGetTodoById
создает селектор, который принимает todoId
в качестве параметра и возвращает задачу с указанным идентификатором.
Использование селекторов с параметрами в компонентах
Теперь рассмотрим, как использовать селекторы с параметрами в компонентах:
import React from 'react';
import { useSelector } from 'react-redux';
import { makeGetTodoById } from './selectors';
const TodoItem = ({ todoId }) => {
const getTodoById = React.useMemo(makeGetTodoById, []);
const todo = useSelector(state => getTodoById(state, todoId));
return (
<div>
<h2>{todo.text}</h2>
<p>{todo.description}</p>
</div>
);
};
export default TodoItem;
Здесь мы используем makeGetTodoById
для создания селектора и хук useSelector
для получения данных задачи по ее идентификатору.
Заключение
Reselect
— это мощный инструмент для создания мемоизированных селекторов в приложениях на Redux. Он помогает улучшить производительность приложения, предотвращая ненужные перерасчеты данных. Надеемся, что приведенные примеры помогут вам начать использовать эту библиотеку в ваших проектах.