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

Зачем нужен State Manager для вынесения бизнес-логики?

1.2 Junior🔥 171 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

State Manager для вынесения бизнес-логики

State Manager (менеджер состояния) — это инструмент для централизованного управления состоянием приложения и отделения бизнес-логики от компонентов представления. Это критически важный паттерн в масштабируемых приложениях.

Проблема без State Manager

Без State Manager'а бизнес-логика размазана по компонентам:

// Плохо: логика в компоненте
function UserProfile() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  
  const fetchUser = async (id) => {
    setLoading(true);
    try {
      const response = await fetch(`/api/users/${id}`);
      const data = await response.json();
      setUser(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };
  
  const updateUser = async (updatedData) => {
    setLoading(true);
    try {
      const response = await fetch(`/api/users/${user.id}`, {
        method: "PUT",
        body: JSON.stringify(updatedData)
      });
      const updated = await response.json();
      setUser(updated);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };
  
  useEffect(() => {
    fetchUser(userId);
  }, [userId]);
  
  return (
    <div>
      {loading && <p>Loading...</p>}
      {error && <p>Error: {error}</p>}
      {user && <p>{user.name}</p>}
    </div>
  );
}

Проблемы:

  • Логика размазана в компоненте
  • Сложно переиспользовать эту логику в других компонентах
  • Сложно тестировать
  • Компонент отвечает за слишком многое

Решение: State Manager

State Manager выносит логику из компонентов:

// 1. Создаём хранилище состояния
const useUserStore = create((set) => ({
  user: null,
  loading: false,
  error: null,
  
  // Бизнес-логика
  fetchUser: async (id) => {
    set({ loading: true, error: null });
    try {
      const response = await fetch(`/api/users/${id}`);
      const data = await response.json();
      set({ user: data });
    } catch (err) {
      set({ error: err.message });
    } finally {
      set({ loading: false });
    }
  },
  
  updateUser: async (updatedData) => {
    set({ loading: true, error: null });
    try {
      const response = await fetch(`/api/users/${user.id}`, {
        method: "PUT",
        body: JSON.stringify(updatedData)
      });
      const updated = await response.json();
      set({ user: updated });
    } catch (err) {
      set({ error: err.message });
    } finally {
      set({ loading: false });
    }
  }
}));

// 2. Компонент становится простым и чистым
function UserProfile({ userId }) {
  const { user, loading, error, fetchUser } = useUserStore();
  
  useEffect(() => {
    fetchUser(userId);
  }, [userId, fetchUser]);
  
  return (
    <div>
      {loading && <p>Loading...</p>}
      {error && <p>Error: {error}</p>}
      {user && <p>{user.name}</p>}
    </div>
  );
}

Основные преимущества State Manager

1. Разделение ответственности (Separation of Concerns)

Без State Manager:

// Компонент отвечает за всё
function Component() {
  const [state, setState] = useState(...);
  const [loading, setLoading] = useState(...);
  const [error, setError] = useState(...);
  
  const handleClick = async () => { /* логика */ };
  const validate = () => { /* логика */ };
  const transform = () => { /* логика */ };
  
  return <div>...</div>; // Представление
}

С State Manager:

// Хранилище: бизнес-логика
const store = {
  state: { /* данные */ },
  fetchData: async () => { /* логика */ },
  validate: () => { /* логика */ },
  transform: () => { /* логика */ }
};

// Компонент: только представление
function Component() {
  const { state, fetchData } = useStore();
  return <div>...</div>;
}

2. Переиспользование логики

// Одна логика используется во многих компонентах
function UserProfile() {
  const { user, fetchUser } = useUserStore();
  // ...
}

function UserCard() {
  const { user, fetchUser } = useUserStore();
  // ...
}

function UserList() {
  const { users, fetchUsers } = useUserStore();
  // ...
}

3. Тестируемость

// Легко тестировать логику отдельно
import { renderHook, act } from '@testing-library/react';
import { useUserStore } from './store';

test('fetchUser должен загружать данные', async () => {
  const { result } = renderHook(() => useUserStore());
  
  act(() => {
    result.current.fetchUser(1);
  });
  
  // Логика в хранилище — полностью изолирована
  expect(result.current.user).toBeDefined();
});

4. Производительность

State Manager'ы оптимизируют re-renders, подписывая компоненты только на нужные части состояния:

// Zustand автоматически оптимизирует подписки
function UserName() {
  const user = useUserStore(state => state.user); // Подписка только на user
}

function LoadingIndicator() {
  const loading = useUserStore(state => state.loading); // Подписка только на loading
}

// Когда меняется loading, UserName не re-renderится

5. Отладка и DevTools

State Manager'ы часто имеют DevTools для отладки:

// Zustand
const useUserStore = create(
  devtools(persistMiddleware(store))
);

// Redux DevTools
// Можно видеть историю всех действий и состояния

Популярные State Manager'ы

ИнструментПлюсыМинусы
ReduxМощный, большое сообществоМного boilerplate
ZustandПростой, лёгкийМеньше функционала
RecoilГибкий, от FacebookНестабильный
TanStack QueryДля API данныхНе универсален
Context APIВстроена в ReactЧасто недостаточно

Когда использовать State Manager

Используй State Manager, если:

  • Логика сложная и повторяется
  • Состояние нужно в разных компонентах
  • Нужна отладка и логирование
  • Приложение среднее или большое

Не нужен State Manager, если:

  • Приложение маленькое
  • Состояние используется в одном компоненте
  • Логика простая

Вывод

State Manager — это критический инструмент для отделения бизнес-логики от представления. Это делает код более чистым, тестируемым и поддерживаемым. В современной разработке React это практически обязательный паттерн для любого приложения среднего размера и больше.

Зачем нужен State Manager для вынесения бизнес-логики? | PrepBro