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

Что такое Effector?

2.0 Middle🔥 181 комментариев
#State Management

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

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

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

Что такое Effector?

Effector — это современная библиотека управления состоянием (state management) для JavaScript и TypeScript приложений. Она разработана для создания предсказуемых, типобезопасных и масштабируемых приложений с чистой архитектурой. Effector используется в production-приложениях и предоставляет альтернативу Redux, Zustand, Jotai и другим решениям.

Основные концепции

Event — это событие, которое можно запустить извне. События — точки входа для действий пользователя, API ответов и других внешних событий:

import { createEvent } from "effector";

const userClicked = createEvent();
const fetchUserFailed = createEvent();

userClicked();
fetchUserFailed(new Error("Network error"));

Store — это хранилище состояния. Store реактивна и уведомляет подписчиков об изменениях:

import { createStore, createEvent } from "effector";

const counterIncremented = createEvent();
const $count = createStore(0)
  .on(counterIncremented, (state) => state + 1);

$count.watch(console.log); // автоматически логирует при изменении
countCounterIncremented();

Effect — асинхронная операция, похожая на Redux Thunk, но более типизированная и предсказуемая:

import { createEffect } from "effector";

const fetchUserFx = createEffect(async (userId: string) => {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
});

fetchUserFx.doneData.watch((user) => console.log("User loaded:", user));
fetchUserFx.failData.watch((error) => console.error("Error:", error));

await fetchUserFx("123");

Связь между примитивами

Effector использует декларативный подход для связи примитивов. Все взаимодействия описываются явно:

const resetClicked = createEvent();
const $count = createStore(0)
  .on(counterIncremented, (state) => state + 1)
  .on(resetClicked, () => 0);

// Автоматическое срабатывание
$count.on(fetchUserFx.doneData, (_, user) => user.postsCount);

Computed values (Derived state)

Этот паттерн называется Domain — группировка связанных stores, events и effects:

import { createStore, createEvent, createEffect, sample } from "effector";

const $user = createStore(null);
const $loading = createStore(false);

const fetchUserFx = createEffect(async (id: string) => {
  // ...
});

$loading
  .on(fetchUserFx, () => true)
  .on(fetchUserFx.finally, () => false);

$user.on(fetchUserFx.doneData, (_, user) => user);

Использование в React компонентах

Effector предоставляет хук useUnit для интеграции со Store:

import { useUnit } from "effector-react";

function UserProfile({ userId }: { userId: string }) {
  const { $user, $loading, fetchUserFx } = useUnit({
    $user: userModel.$user,
    $loading: userModel.$loading,
    fetchUserFx: userModel.fetchUserFx,
  });

  React.useEffect(() => {
    fetchUserFx(userId);
  }, [userId, fetchUserFx]);

  if ($loading) return <div>Loading...</div>;
  if (!$user) return <div>Not found</div>;

  return <div>{$user.name}</div>;
}

Преимущества Effector

  • Типобезопасность: полная поддержка TypeScript с автоматическим выводом типов
  • Предсказуемость: данные всегда в одном месте, нет скрытых побочных эффектов
  • DevTools: мощный инструмент для отладки состояния
  • Производительность: оптимизированное отслеживание зависимостей
  • Масштабируемость: органично растет с размером приложения

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

Effector рекомендуется для:

  • Сложного управления состоянием с асинхронными операциями
  • Больших приложений, где важна типизация
  • Проектов, требующих предсказуемого поведения

Для простых приложений может быть избыточным — в таких случаях лучше использовать useState/useContext или более легкие решения вроде Zustand.