Приведи пример использования Effector в Next

Ответ

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>
  );
}

Ключевые моменты:

  1. Используем Provider в корневом layout
  2. Для клиентских компонентов добавляем 'use client'
  3. Состояние сохраняется при навигации
  4. Для 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 живут как кот и собака в одной квартире — вроде и дерутся иногда, но в целом уживаются.