Управление состоянием в Astro с помощью Nano Stores
Кратко
Кратко: в этой статье показано, как интегрировать Nano Stores в проект Astro, чтобы управлять состоянием и разделять его между компонентами на React и Solid. Пошаговые примеры, готовые сниппеты и чеклисты помогут быстро внедрить хранилище заметок и проверять работу.

О чём этот материал
Эта статья покажет: установка Astro и Nano Stores, создание простого хранилища заметок, компонент на React для добавления заметок, компонент на Solid для чтения тех же заметок и советы по интеграции, тестированию и выбору альтернатив. Подойдёт разработчикам фронтенда, желающим минимизировать клиентский JS и при этом поддерживать интерактивность.
Что такое Astro?
Astro — это фреймворк для создания контентно-ориентированных веб‑сайтов, который объединяет компоненты из популярных UI‑библиотек (React, Preact, Vue, Svelte и др.). Основная идея — рендерить страницы на сервере и минимизировать объём JavaScript на клиенте, отправляя только ту часть, которая нужна для интерактивности.
Ключевая особенность: вы помечаете компоненты как интерактивные (client:load, client:idle, client:visible и т.д.), и Astro отправит для них минимальный JS. Это делает Astro удобным для блогов, лендингов и сайтов с преимущественно контентной составляющей.
Когда использовать Nano Stores с Astro
Nano Stores — лёгкий state manager, совместимый с React, Preact, Svelte, Solid, Lit, Angular и Vanilla JS. Он хорош, когда нужно:
- Локальное и простое глобальное состояние без громоздкой инфраструктуры.
- Быстрая синхронизация состояния между компонентами, написанными на разных фреймворках.
- Малый объём зависимостей и предсказуемое поведение атомарных хранилищ.
Важно: для сложных бизнес‑логик или если нужен time‑travel/debugging как в Redux, Nano Stores может быть не лучшим выбором.
Требования и подготовка
Требуется установленный Node.js и рабочий проект Astro. Если проекта нет — создайте его и добавьте React (и по желанию Solid):
npm create astro@latestЗатем в корне проекта добавьте React:
npx astro add reactУстановите Nano Stores для React:
npm i nanostores @nanostores/reactЗапустите локальную разработку:
npm run devПосле запуска откройте http://localhost:3000
Создание хранилища заметок (noteStore.js)
В папке src создайте файл noteStore.js и экспортируйте atom и функции управления заметками. Пример рабочего варианта:
import { atom } from "nanostores"
export const notes = atom([])
export function addNote(note) {
// Получаем текущий массив, создаём новый — без мутаций
notes.set([...notes.get(), note])
console.log("Added note:", note)
}Коротко о терминах: atom — атомарное хранилище для небольших значений (массивов, объектов, строк). get/set — методы для чтения/записи.
UI: компонент React для добавления заметок (NoteAddButton.jsx)
Создайте src/components/NoteAddButton.jsx. Этот компонент собирает текст от пользователя, отправляет в addNote и показывает текущий список заметок из хранилища.
import { useState } from "react"
import { useStore } from "@nanostores/react"
import { addNote, notes } from "../noteStore"
export default function NoteAdder() {
const [userNote, setUserNote] = useState("")
const $notes = useStore(notes)
return (
<>
setUserNote(event.target.value)}
/>
{$notes.map((note, index) => (
- {note}
))}
>
)
}Важно: мы используем useStore из @nanostores/react, чтобы компонент автоматически подписывался на изменения notes.
Подключение компонента в pages/index.astro
Откройте pages/index.astro и импортируйте компонент. Пометьте его клиентским директивом (например, client:load), чтобы компонент и его логика работали на клиенте:
import NoteAddButton from "../components/NoteAddButton.jsx"
---
// Остальной кодТеперь в браузере вы увидите поле ввода и кнопку. При сохранении заметка появится на странице и сохранится в хранилище до перезагрузки (в рамках текущей сессии/памяти страницы).
Поделить состояние между React и Solid
Если нужно, чтобы одни и те же данные читали компоненты на разных фреймворках, Nano Stores отлично подходит.
- Добавьте Solid в проект:
npx astro add solid- Установите адаптер Nano Stores для Solid:
npm i nanostores @nanostores/solid- Создайте компонент на Solid (src/components/Notes.jsx):
import { useStore } from "@nanostores/solid"
import { notes } from "../noteStore"
import { For } from "solid-js"
export default function Notes() {
const $notes = useStore(notes)
return (
<>
My notes
{(note) => - {note}
}
>
)
}- Подключите оба компонента в pages/index.astro:
import NoteAddButton from "../components/NoteAddButton.jsx"
import Notes from "../components/Notes.jsx"
---
// Остальной кодПосле этого заметки, добавленные через React‑компонент, будут видны и в Solid‑компоненте — хранилище одно и то же.
Практический плейбук: как внедрить Nano Stores в проект Astro (шаги)
- Подготовка: убедитесь, что в проекте установлены React и/или Solid. Установите nanostores и соответствующие адаптеры.
- Создайте атомы (atom) для каждой логической единицы состояния (список заметок, настройки, пользователь).
- Экспортируйте функции‑обёртки (add/remove/update), чтобы минимизировать повсеместные set/get.
- Для React: используйте useStore из @nanostores/react. Для Solid: useStore из @nanostores/solid.
- Встраивайте компоненты с директивой client:* по потребности (client:load/client:idle/client:visible).
- Покройте базовые сценарии тестами и приёмкой (см. раздел Критерии приёмки).
Ментальная модель и эвристики
- Atom = источник правды для одной сущности. Думайте об atom как о маленьком, независимом Redux store.
- Читайте через адаптер useStore (клиентские компоненты). Пишите через экспортированные функции (action‑подобные).
- Избегайте сложных вычислений в atom; переместите их в селекторы/функции, чтобы хранилища оставались простыми.
Когда Nano Stores может не подойти (контрпример)
- Нужна мощная архитектура для глобального состояния с историей (time travel), средством отладки и middleware — тогда лучше Redux/Redux Toolkit.
- Сложные асинхронные потоки и side‑effects, тесно связанные с состоянием, могут потребовать RxJS или MobX.
- Если проект требует глубокой интеграции со сторонними devtools, Nano Stores предоставляет базовый набор, но не все расширения.
Альтернативы и сравнение (кратко)
- Redux / Redux Toolkit — сильно структурировано, больше boilerplate, продвинутые devtools.
- Zustand — лёгкий и удобный для React, похож по философии, но менее мультифреймворковый.
- Context API (React) — подойдёт для простых задач в пределах React, но не для мультифреймворковых приложений.
- RxJS — мощно для сложных реактивных потоков, но более крутая кривая обучения.
Критерии приёмки
- Добавление заметки через React‑компонент отображает её в списках React и Solid.
- Компоненты автоматически обновляются при изменении atom без ручного рендера.
- Нет ошибок в консоли при типичных сценариях (добавление/удаление пустой строки).
- Поведение при перезагрузке страницы соответствует ожиданиям (в памяти страницы — заметки исчезают; для сохранения — нужна персистенция).
Тестовые сценарии / Acceptance criteria
- Добавить простую заметку «test» — она появляется в обоих компонентах.
- Попытка добавить пустую или пробельную заметку — не записывается.
- Быстрая серия добавлений не приводит к потере данных (массив обновляется корректно).
- Удаление/изменение заметки (если реализовано) синхронизировано между фреймворками.
Чеклисты по ролям
Разработчик:
- Установил nanostores и адаптеры
- Создал atom и функции изменения
- Подключил useStore в компонентах
- Добавил client:* директивы
QA / Тестировщик:
- Прогнал тестовые сценарии из раздела выше
- Проверил консоль на ошибки
- Тестировал взаимодействие React ↔ Solid
DevOps:
- Проверил сборку на сервере
- Убедился, что нативный SSR Astro не включает лишний клиентский JS
Совместимость и миграция
- Nano Stores работает с большинством UI‑фреймворков, но убедитесь, что адаптеры (@nanostores/react, @nanostores/solid) совместимы с версиями ваших библиотек.
- В Astro используйте client:load/client:idle/client:visible аккуратно — лишняя загрузка клиентского JS уменьшит преимущества Astro.
Совет по миграции: начните с одного простого atom и одного компонента — убедитесь, что подписки работают, затем постепенно переводите остальное состояние.
Безопасность и приватность
Хранилища Nano Stores находятся в памяти клиента (если не реализована персистенция). Не храните секреты или персональные данные в неизолированном виде. Для персистенции используйте шифрование или сервер‑сторирование.
Краткое резюме
Nano Stores — удобный инструмент для лёгкого глобального состояния, особенно если ваш проект на Astro совмещает несколько UI‑фреймворков. Он прост в установке, минимален по зависимостям и позволяет быстро обмениваться данными между компонентами. Для сложных случаев рассмотрите более мощные менеджеры состояния.
Полезные заметки
Important: при использовании в продакшене решите, как и где хранить данные долговременно (localStorage, IndexedDB, сервер). Nano Stores отвечает за синхронизацию в памяти — персистенция и миграция данных — отдельная задача.
Сводка
- Nano Stores хорошо подходит для мультифреймворковых проектов на Astro.
- Простая архитектура: atom + адаптеры (React/Solid).
- Проверьте альтернативы при сложных требованиях и добавьте слой персистенции при необходимости.