# Effector Guide This guide provides an overview of how to use Effector in our application, following our Flux-style architecture. ## Core Concepts Effector is a state management library that implements the Flux pattern with three main primitives: 1. **Events**: Trigger state changes 2. **Stores**: Hold application state 3. **Effects**: Handle side effects (async operations) ## Basic Usage ### Creating Events Events are functions that can be called to trigger state changes: ```typescript import { createEvent } from 'effector'; // Create an event export const increment = createEvent(); export const addTodo = createEvent(); export const updateUser = createEvent<{ name: string, email: string }>(); // Call the event increment(); addTodo('Buy milk'); updateUser({ name: 'John', email: 'john@example.com' }); ``` ### Creating Stores Stores hold the application state and update in response to events: ```typescript import { createStore } from 'effector'; import { increment, addTodo } from './events'; // Create a store with initial state export const $counter = createStore(0) .on(increment, state => state + 1); export const $todos = createStore([]) .on(addTodo, (state, todo) => [...state, todo]); ``` ### Creating Effects Effects handle asynchronous operations: ```typescript import { createEffect } from 'effector'; import { api } from '@shared/lib/api'; // Create an effect export const fetchUserFx = createEffect(async (userId: string) => { const response = await api.getUser(userId); return response.data; }); // Call the effect fetchUserFx('123'); ``` ### Handling Effect States Effects have three states: pending, done, and fail: ```typescript import { createStore } from 'effector'; import { fetchUserFx } from './effects'; // Create stores for different effect states export const $isLoading = createStore(false) .on(fetchUserFx.pending, (_, isPending) => isPending); export const $user = createStore(null) .on(fetchUserFx.doneData, (_, user) => user); export const $error = createStore(null) .on(fetchUserFx.failData, (_, error) => error) .on(fetchUserFx, () => null); // Reset error when effect is called ``` ## Using with React ### useStore Hook The `useStore` hook connects Effector stores to React components: ```typescript import { useStore } from 'effector-react'; import { $counter, increment } from './model'; const Counter = () => { const count = useStore($counter); return (

Count: {count}

); }; ``` ### useEvent Hook The `useEvent` hook creates a stable callback for events: ```typescript import { useStore, useEvent } from 'effector-react'; import { $todos, addTodo } from './model'; const TodoList = () => { const todos = useStore($todos); const handleAddTodo = useEvent(addTodo); return (
    {todos.map((todo, index) => (
  • {todo}
  • ))}
); }; ``` ## Advanced Patterns ### Derived Stores (Computed Values) Create derived stores using the `.map` method: ```typescript import { createStore } from 'effector'; export const $todos = createStore([ { id: 1, text: 'Buy milk', completed: false }, { id: 2, text: 'Clean house', completed: true } ]); // Derived store for completed todos export const $completedTodos = $todos.map( todos => todos.filter(todo => todo.completed) ); // Derived store for todo count export const $todoCount = $todos.map(todos => todos.length); ``` ### Combining Stores Combine multiple stores into one: ```typescript import { createStore, combine } from 'effector'; export const $user = createStore({ name: 'John' }); export const $settings = createStore({ theme: 'dark' }); // Combined store export const $appState = combine({ user: $user, settings: $settings }); // Or with a custom mapper function export const $userData = combine( $user, $settings, (user, settings) => ({ ...user, theme: settings.theme }) ); ``` ### Reset Events Reset stores to their initial state: ```typescript import { createEvent, createStore } from 'effector'; export const reset = createEvent(); export const $counter = createStore(0) .reset(reset); // Reset to initial state (0) // Call reset to restore initial state reset(); ``` ## Best Practices 1. **Keep model.ts pure**: Avoid side effects in store updates. 2. **Use TypeScript**: Define types for all events, stores, and effects. 3. **Organize by domain**: Group related events, stores, and effects in domain folders. 4. **Use view-model.ts**: Create hooks that encapsulate Effector logic for React components. 5. **Keep UI components simple**: UI components should only consume data from hooks and call events. 6. **Test model.ts**: Write unit tests for your Effector logic.