Ответ
Effector отлично интегрируется с Next.js, особенно с App Router. Вот пример:
// store.ts
import { createStore, createEvent } from 'effector';
export const increment = createEvent();
export const $count = createStore(0)
.on(increment, (state) => state + 1);
// app/layout.tsx
import { Provider } from 'effector-react';
import { $count, increment } from './store';
export default function RootLayout({ children }) {
return (
<Provider>
<html>
<body>{children}</body>
</html>
</Provider>
);
}
// app/page.tsx
'use client';
import { useStore } from 'effector-react';
import { $count, increment } from './store';
export default function Home() {
const count = useStore($count);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => increment()}>Increment</button>
</div>
);
}
Ключевые моменты:
- Используем
Providerв корневом layout - Для клиентских компонентов добавляем 'use client'
- Состояние сохраняется при навигации
- Для SSR можно использовать
forkиserialize
Ответ 18+ 🔞
А, ну ты смотри, опять про эти ваши модные штуки с состоянием! Effector, говоришь? Ну, блядь, это ж как раз про то, как не сойти с ума в Next.js, особенно с этим ихним App Router, который сам чёрт ногу сломит.
Слушай сюда, я тебе сейчас как на пальцах объясню, чтоб даже мой кот, сука, понял. Вот смотри, обычный store делается проще пареной репы:
// store.ts
import { createStore, createEvent } from 'effector';
export const increment = createEvent();
export const $count = createStore(0)
.on(increment, (state) => state + 1);
Видишь? Создали событие increment — это как крикнуть "эй, добавь единичку!". А $count — это просто ящик, где цифра лежит. Когда событие прилетает, ящик обновляется. Всё, ебать, элементарно!
Теперь самое интересное — как это впихнуть в Next.js, чтобы не вышло как всегда. В корневом layout'е вешаем Provider, чтоб всё работало:
// app/layout.tsx
import { Provider } from 'effector-react';
import { $count, increment } from './store';
export default function RootLayout({ children }) {
return (
<Provider>
<html>
<body>{children}</body>
</html>
</Provider>
);
}
Provider — это как, блядь, мамка для всех компонентов. Даёт им доступ к общему состоянию, чтобы они не дрались как папуасы за последнюю конфету.
А теперь клиентский компонент, где вся магия происходит:
// app/page.tsx
'use client';
import { useStore } from 'effector-react';
import { $count, increment } from './store';
export default function Home() {
const count = useStore($count);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => increment()}>Increment</button>
</div>
);
}
Видишь эту хуйню 'use client' в самом верху? Это как крикнуть Next.js: "Эй, братан, этот компонент — клиентский, тут можно хуярить состояние и обработчики, а не просто статику показывать!" Без этой строчки он тебе, блядь, мозги вынесет ошибками.
И главное — состояние-то сохраняется при навигации! Нажал кнопку, цифра поменялась, перешёл на другую страницу и обратно — а она, сука, на месте! Не сбрасывается, как у тех, кто на хуйню какую-то полагается.
Ну а если тебе SSR нужен, там, блядь, целая история с fork и serialize. Это уже для продвинутых, когда надо серверу сначала состояние приготовить, а потом клиенту скормить. Но это, как говорится, уже совсем другая, ебать, сказка.
Короче, ничего сложного. Главное — не перемудрить и не пытаться, блядь, изобрести велосипед с реактивными педалями. Effector с Next.js живут как кот и собака в одной квартире — вроде и дерутся иногда, но в целом уживаются.