Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: React, custom hook, reusable component, composition, state management

Как избежать дублирования бизнес-логики (управление страницей, сортировкой) при использовании одного и того же компонента таблицы в разных местах приложения?

Вопрос проверяет понимание подходов к переиспользованию компонентов таблицы с общей бизнес-логикой в React-приложениях.

Короткий ответ

Для избежания дублирования бизнес-логики таблицы вынесите общую логику (пагинацию, сортировку, фильтрацию) в кастомный хук, например useTable. Компонент таблицы принимает пропсы и использует этот хук. В разных местах приложения вы просто вызываете хук с разными настройками и передаёте результат в один и тот же компонент таблицы. Это позволяет переиспользовать и логику, и представление без копирования кода.

Длинный ответ

Проблема дублирования бизнес-логики таблицы

Когда один и тот же компонент таблицы используется в разных частях приложения, часто возникает соблазн скопировать логику пагинации, сортировки и фильтрации в каждый родительский компонент. Это приводит к дублированию кода, усложняет поддержку и увеличивает риск ошибок.

Решение: кастомный хук + переиспользуемый компонент

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

// useTable.js
import { useState, useMemo } from 'react';

export function useTable(data, config) {
  const [page, setPage] = useState(1);
  const [sortBy, setSortBy] = useState(null);
  const [filter, setFilter] = useState('');

  const processedData = useMemo(() => {
    let result = [...data];
    if (filter) {
      result = result.filter(item =>
        item.name.toLowerCase().includes(filter.toLowerCase())
      );
    }
    if (sortBy) {
      result.sort((a, b) => (a[sortBy] > b[sortBy] ? 1 : -1));
    }
    const pageSize = config.pageSize || 10;
    const start = (page - 1) * pageSize;
    return result.slice(start, start + pageSize);
  }, [data, page, sortBy, filter, config]);

  return { processedData, page, setPage, sortBy, setSortBy, filter, setFilter };
}
// Table.jsx
function Table({ data, onSort, onFilter, columns }) {
  return (
    <table>
      <thead>
        <tr>
          {columns.map(col => (
            <th key={col.key} onClick={() => onSort(col.key)}>
              {col.label}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {data.map(row => (
          <tr key={row.id}>
            {columns.map(col => (
              <td key={col.key}>{row[col.key]}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Применение в разных частях приложения

Теперь в любом компоненте, где нужна таблица, вы просто используете хук и передаёте результат в компонент:

// UsersPage.jsx
function UsersPage() {
  const { processedData, page, setPage, sortBy, setSortBy, filter, setFilter } =
    useTable(usersData, { pageSize: 20 });

  return (
    <div>
      <input value={filter} onChange={e => setFilter(e.target.value)} />
      <Table
        data={processedData}
        onSort={setSortBy}
        columns={[
          { key: 'name', label: 'Name' },
          { key: 'email', label: 'Email' },
        ]}
      />
      <button onClick={() => setPage(page - 1)} disabled={page === 1}>Prev</button>
      <span>Page {page}</span>
      <button onClick={() => setPage(page + 1)}>Next</button>
    </div>
  );
}

Аналогично для страницы заказов — просто вызываете useTable(ordersData, { pageSize: 10 }) и передаёте другие колонки.

Вывод

Использование кастомного хука для бизнес-логики таблицы и презентационного компонента для отображения позволяет полностью избежать дублирования кода. Этот подход легко масштабируется, упрощает тестирование и делает приложение более поддерживаемым. Рекомендуется применять для любых повторяющихся UI-паттернов с общей логикой.

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#React

#custom hook

#reusable component

#composition

#state management

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию