← Назад к вопросам

Приведи пример использования стейта компонента вместо стейта Redux

2.0 Middle🔥 211 комментариев
#HTML и CSS#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда стоит использовать стейт компонента вместо Redux

В современной фронтенд-разработке часто возникает дилемма: хранить данные в локальном стейте компонента или в глобальном стейте Redux. Ответ зависит от конкретных требований приложения. Локальный стейт компонента идеально подходит для изолированных данных, которые не нужны другим частям приложения.

Практический пример: компонент фильтрации данных

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

import React, { useState } from 'react';

const ProductFilter = ({ products, onFilter }) => {
  // Локальный стейт для значений фильтров
  const [minPrice, setMinPrice] = useState(0);
  const [maxPrice, setMaxPrice] = useState(1000);
  const [selectedCategory, setSelectedCategory] = useState('all');
  
  // Данные для фильтрации по категориям
  const categories = ['all', 'electronics', 'clothing', 'books', 'home'];
  
  const handleFilterChange = () => {
    // Применяем фильтры локально
    const filteredProducts = products.filter(product => {
      const priceMatch = product.price >= minPrice && product.price <= maxPrice;
      const categoryMatch = selectedCategory === 'all' || product.category === selectedCategory;
      return priceMatch && categoryMatch;
    });
    
    // Передаем отфильтрованные данные родительскому компоненту
    onFilter(filteredProducts);
  };
  
  // Сбрасываем фильтры к значениям по умолчанию
  const handleReset = () => {
    setMinPrice(0);
    setMaxPrice(1000);
    setSelectedCategory('all');
    onFilter(products);
  };
  
  return (
    <div className="filter-panel">
      <h3>Фильтр товаров</h3>
      
      <div className="filter-group">
        <label>Минимальная цена: ${minPrice}</label>
        <input
          type="range"
          min="0"
          max="1000"
          value={minPrice}
          onChange={(e) => setMinPrice(Number(e.target.value))}
        />
      </div>
      
      <div className="filter-group">
        <label>Максимальная цена: ${maxPrice}</label>
        <input
          type="range"
          min="0"
          max="2000"
          value={maxPrice}
          onChange={(e) => setMaxPrice(Number(e.target.value))}
        />
      </div>
      
      <div className="filter-group">
        <label>Категория:</label>
        <select 
          value={selectedCategory} 
          onChange={(e) => setSelectedCategory(e.target.value)}
        >
          {categories.map(category => (
            <option key={category} value={category}>
              {category}
            </option>
          ))}
        </select>
      </div>
      
      <div className="filter-actions">
        <button onClick={handleFilterChange}>Применить фильтры</button>
        <button onClick={handleReset}>Сбросить</button>
      </div>
    </div>
  );
};

export default ProductFilter;

Почему локальный стейт предпочтительнее Redux в этом случае

Аргументы за локальный стейт:

  • Изолированность логики: Состояние фильтров нужно только этому компоненту и его непосредственным детям
  • Простота реализации: Не требуется создавать actions, reducers, селекторы
  • Упрощенное тестирование: Компонент можно тестировать изолированно без настройки Redux store
  • Производительность: Изменения стейта не вызывают глобальных обновлений приложения
  • Снижение сложности: Меньше кода, проще поддерживать

Когда переходить на Redux стоило бы:

  1. Если другие компоненты должны реагировать на изменение фильтров
  2. Если нужно сохранять состояние фильтров между сессиями (в localStorage)
  3. Если состояние фильтров должно синхронизироваться с URL (через query-параметры)
  4. Если несколько независимых компонентов используют одинаковые фильтры

Оптимизация производительности

Для сложных компонентов с локальным стейтом можно использовать мемоизацию:

import React, { useState, useMemo, useCallback } from 'react';

const ExpensiveComponent = ({ data }) => {
  const [filter, setFilter] = useState('');
  const [sortOrder, setSortOrder] = useState('asc');
  
  // Мемоизируем вычисления, зависящие от локального стейта
  const processedData = useMemo(() => {
    console.log('Пересчет данных...');
    return data
      .filter(item => item.name.includes(filter))
      .sort((a, b) => sortOrder === 'asc' 
        ? a.value - b.value 
        : b.value - a.value
      );
  }, [data, filter, sortOrder]);
  
  const handleFilterChange = useCallback((value) => {
    setFilter(value);
  }, []);
  
  return (
    <div>
      <input 
        value={filter} 
        onChange={(e) => handleFilterChange(e.target.value)} 
      />
      {/* Остальной рендеринг */}
    </div>
  );
};

Золотое правило выбора

Используйте подход "сначала локальный стейт", пока не появится явная необходимость в глобальном состоянии. Redux следует применять для данных, которые:

  • Используются множеством компонентов в разных частях приложения
  • Должны сохраняться при навигации
  • Требуют сложных преобразований или middleware
  • Нуждаются в отслеживании истории изменений

Локальный стейт компонента — это не "упрощенная" версия Redux, а самостоятельный инструмент с четкой областью применения. Его правильное использование делает приложение более производительным, а код — более понятным и простым в поддержке.

Приведи пример использования стейта компонента вместо стейта Redux | PrepBro