Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое 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.