Фильтрация заказов по имени написанный с использованием redux и debounceно без toolkit

Для фильтрации заказов по имени с использованием Redux и debounce, но без @reduxjs/toolkit, мы можем сделать следующее:

  1. Создадим actions, reducer, и store для Redux.
  2. Добавим debounce с использованием setTimeout для задержки перед применением фильтрации.

Шаги:

  1. Создание действий (Actions):
  • Мы будем использовать два действия: одно для фильтрации заказов по имени, другое для обновления значения фильтра.
  1. Reducer:
  • В редьюсере будем отслеживать список заказов и строку фильтра, и фильтровать заказы в зависимости от значения фильтра.
  1. Store:
  • Создадим Redux store для управления состоянием.
  1. Компонент для отображения заказов и фильтра:
  • Будем использовать useDispatch для отправки действий и useSelector для получения состояния заказов из Redux.
  1. 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;

Объяснение:

  1. Actions:
  • setFilter: обновляет строку фильтра.
  • filterOrders: выполняет фильтрацию заказов в состоянии Redux.
  1. Reducer:
  • Содержит логику фильтрации заказов. При изменении фильтра, мы фильтруем список заказов в filteredOrders на основе значения фильтра.
  1. Store:
  • Redux store содержит состояние заказов, строку фильтра и отфильтрованные заказы. Мы используем redux-thunk для возможной работы с асинхронными действиями.
  1. Компонент OrdersFilter:
  • Компонент содержит поле ввода для фильтрации заказов по имени. Мы используем setTimeout для debounce, чтобы задержать вызов действия фильтрации и избежать излишних обновлений при каждом вводе символа.
  1. Debounce:
  • Используем setTimeout для задержки вызова фильтрации на 300 миллисекунд после последнего ввода, чтобы предотвратить излишнюю нагрузку при быстром наборе текста.

Таким образом, фильтрация заказов по имени будет происходить с использованием Redux и debounce, без использования @reduxjs/toolkit.


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *