Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чим Effector відрізняється від Redux?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Effector і Redux** - обидва менеджери стану, але побудовані на різних філософіях: Effector - реактивна, декларативна система, а Redux - імперативна, редьюсерна архітектура. **Ключове:** Effector описує потік даних і оновлюється автоматично за залежностями, а Redux описує, як reducer змінює store, і оновлюється вручну через `dispatch()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняEffector і Redux - це **обидва менеджери стану**, але вони **побудовані на зовсім різних філософіях**. Якщо коротко: > Effector - **реактивна, декларативна система**; > Redux - **імперативна, редьюсерна архітектура**. Розберемо **по пунктах і з прикладами**. --- ## 1. Підхід до керування станом | | **Effector** | **Redux / RTK** | |---|---|---| | **Парадигма** | Реактивна | Імперативна | | **Як описується логіка** | "Що залежить від чого" (dataflow) | "Що робити, коли сталася подія" (reducers) | | **Оновлення** | Автоматичні за залежностями | Ручні через `dispatch()` | | **Філософія** | Опиши потік даних | Опиши, як reducer змінює store | Effector: ```javascript const increment = createEvent() const $count = createStore(0).on(increment, c => c + 1) ``` Redux: ```javascript const increment = () => ({ type: 'increment' }) const reducer = (state = 0, action) => action.type === 'increment' ? state + 1 : state ``` --- ## 2. Архітектура і принципи | | **Effector** | **Redux** | |---|---|---| | **Стан** | Декілька незалежних `store` | Один великий `store` (або slices) | | **Сайд-ефекти** | Через `createEffect()` (вбудовано) | Через `thunk`, `saga`, `observable` тощо | | **Підписки** | Реактивні (`.watch`, `.map`, `sample`) | Через `useSelector()` / middleware | | **Типізація** | Відмінна інтеграція з TypeScript | Краще з Redux Toolkit, але все одно громіздко | | **Продуктивність** | Мінімальні ререндери, fine-grained реактивність | Може викликати зайві ререндери | | **SSR** | Із коробки | Потрібне ручне керування станом | --- ## 3. Робота з асинхронністю Effector вбудовано керує асинхронними ефектами: ```javascript const fetchUserFx = createEffect(async id => { const res = await fetch(`/api/users/${id}`) return res.json() }) fetchUserFx.done.watch(({ result }) => console.log('User', result)) ``` У Redux потрібно вручну писати middleware: ```javascript const fetchUser = id => async dispatch => { dispatch({ type: 'pending' }) const res = await fetch(`/api/users/${id}`) dispatch({ type: 'success', payload: await res.json() }) } ``` Effector робить це декларативно, без middleware. --- ## 4. Гнучкість і масштабування Effector дозволяє описувати залежності явно: ```javascript sample({ source: $user, clock: updateClicked, fn: (user) => ({ ...user, updated: true }), target: $user, }) ``` У Redux подібний реактивний зв'язок неможливий - потрібно вручну диспатчити ланцюжок дій. Effector не вимагає глобального стора: ти можеш створити локальний `store` для будь-якого компонента або модуля. Redux же передбачає **єдину централізовану структуру** (store -> reducer tree). --- ## 5. Продуктивність і підписки Effector підписує компонент **тільки на потрібні дані**. При зміні інших `store` компонент не ререндериться. Redux, навіть з `useSelector`, часто викликає **зайві ререндери**, якщо не використовувати мемоізацію (`shallowEqual`, `reselect` тощо). --- ## 6. Код і DX (Developer Experience) Effector: ```javascript const addTodo = createEvent<string>() const $todos = createStore<string[]>([]).on(addTodo, (list, todo) => [...list, todo]) ``` Redux Toolkit: ```javascript const todosSlice = createSlice({ name: 'todos', initialState: [], reducers: { addTodo: (state, action) => { state.push(action.payload) } } }) ``` Effector - **менше шаблонного коду**, більше декларативності і реактивних зв'язків. Redux Toolkit - **більш імперативний**, але знайомий розробникам зі старих екосистем. --- ## 7. Коли обрати що | Сценарій | Що обрати | |---|---| | Маленький застосунок | Zustand, Jotai, Effector | | Великий SPA з бізнес-логікою | **Effector** | | Enterprise / Legacy / знайома команда | **Redux Toolkit** | | Потрібен строгий dataflow і реактивність | **Effector** | | Потрібен зрозумілий "по кроках" флоу | **Redux Toolkit** | --- ## 8. Коротко однією фразою > **Effector** - це реактивний dataflow-менеджер: описуєш зв'язки, і все оновлюється саме. > **Redux** - це імперативний action-reducer-менеджер: викликаєш дії, все оновлюється вручну.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.