Для фильтрации заказов по имени с использованием Redux и debounce, но без @reduxjs/toolkit
, мы можем сделать следующее:
- Создадим actions, reducer, и store для Redux.
- Добавим debounce с использованием
setTimeout
для задержки перед применением фильтрации.
Шаги:
- Создание действий (Actions):
- Мы будем использовать два действия: одно для фильтрации заказов по имени, другое для обновления значения фильтра.
- Reducer:
- В редьюсере будем отслеживать список заказов и строку фильтра, и фильтровать заказы в зависимости от значения фильтра.
- Store:
- Создадим Redux store для управления состоянием.
- Компонент для отображения заказов и фильтра:
- Будем использовать
useDispatch
для отправки действий иuseSelector
для получения состояния заказов из Redux.
- Debounce:
- Для debounce мы будем использовать
setTimeout
в обработчике ввода фильтра.
Пример кода:
1. Создание actions
// src/redux/actions/ordersActions.ts
export const SET_FILTER = 'SET_FILTER';
export const FILTER_ORDERS = 'FILTER_ORDERS';
// Action для установки значения фильтра
export const setFilter = (filterValue: string) => ({
type: SET_FILTER,
payload: filterValue,
});
// Action для фильтрации заказов
export const filterOrders = () => ({
type: FILTER_ORDERS,
});
2. Создание reducer
// src/redux/reducers/ordersReducer.ts
import { SET_FILTER, FILTER_ORDERS } from '../actions/ordersActions';
const initialState = {
orders: [
{ id: 1, name: 'Order 1' },
{ id: 2, name: 'Order 2' },
{ id: 3, name: 'Special Order' },
// добавьте больше заказов по вашему усмотрению
],
filteredOrders: [],
filter: '',
};
const ordersReducer = (state = initialState, action: any) => {
switch (action.type) {
case SET_FILTER:
return {
...state,
filter: action.payload, // Устанавливаем значение фильтра
};
case FILTER_ORDERS:
return {
...state,
filteredOrders: state.orders.filter((order) =>
order.name.toLowerCase().includes(state.filter.toLowerCase())
),
};
default:
return state;
}
};
export default ordersReducer;
3. Создание Redux Store
// src/redux/store.ts
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'; // Подключаем redux-thunk для асинхронных действий
import ordersReducer from './reducers/ordersReducer'; // Импортируем редьюсер заказов
// Настроим Redux DevTools
const composeEnhancers =
(typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const store = createStore(
ordersReducer,
composeEnhancers(applyMiddleware(thunk))
);
export default store;
4. Компонент фильтрации заказов с debounce
// src/components/OrdersFilter.tsx
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { setFilter, filterOrders } from '../redux/actions/ordersActions';
const OrdersFilter = () => {
const dispatch = useDispatch();
const [debounceTimeout, setDebounceTimeout] = useState<NodeJS.Timeout | null>(null);
const filterValue = useSelector((state: any) => state.filter);
const filteredOrders = useSelector((state: any) => state.filteredOrders);
// Функция для обработки ввода фильтра
const handleFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
// Если есть предыдущий таймаут, очищаем его
if (debounceTimeout) {
clearTimeout(debounceTimeout);
}
// Устанавливаем новый таймаут
const timeout = setTimeout(() => {
// Устанавливаем значение фильтра в Redux
dispatch(setFilter(value));
// Диспатчим действие для фильтрации заказов после задержки
dispatch(filterOrders());
}, 300); // Устанавливаем задержку 300 мс
setDebounceTimeout(timeout);
};
return (
<div>
<input
type="text"
value={filterValue}
onChange={handleFilterChange}
placeholder="Filter orders by name..."
/>
<ul>
{filteredOrders.length > 0 ? (
filteredOrders.map((order: { id: number; name: string }) => (
<li key={order.id}>{order.name}</li>
))
) : (
<p>No orders found</p>
)}
</ul>
</div>
);
};
export default OrdersFilter;
5. Подключение компонента к приложению
// src/app/page.tsx
import OrdersFilter from '../components/OrdersFilter';
const HomePage = () => {
return (
<div>
<h1>Orders</h1>
<OrdersFilter />
</div>
);
};
export default HomePage;
Объяснение:
- Actions:
setFilter
: обновляет строку фильтра.filterOrders
: выполняет фильтрацию заказов в состоянии Redux.
- Reducer:
- Содержит логику фильтрации заказов. При изменении фильтра, мы фильтруем список заказов в
filteredOrders
на основе значения фильтра.
- Store:
- Redux store содержит состояние заказов, строку фильтра и отфильтрованные заказы. Мы используем
redux-thunk
для возможной работы с асинхронными действиями.
- Компонент
OrdersFilter
:
- Компонент содержит поле ввода для фильтрации заказов по имени. Мы используем
setTimeout
для debounce, чтобы задержать вызов действия фильтрации и избежать излишних обновлений при каждом вводе символа.
- Debounce:
- Используем
setTimeout
для задержки вызова фильтрации на 300 миллисекунд после последнего ввода, чтобы предотвратить излишнюю нагрузку при быстром наборе текста.
Таким образом, фильтрация заказов по имени будет происходить с использованием Redux и debounce, без использования @reduxjs/toolkit
.
Добавить комментарий