Гид по технологиям

Управление состоянием в Astro с помощью Nano Stores

6 min read Веб-разработка Обновлено 07 Jan 2026
Nano Stores в Astro: управление состоянием
Nano Stores в Astro: управление состоянием

Важное: Nano Stores — это лёгкий глобальный стор, совместимый с множеством UI-фреймворков. Он не заменяет архитектуру приложения, но упрощает обмен данными между компонентами разных фреймворков.

Что такое Astro

Astro — это фреймворк для создания веб-приложений и сайтов, который позволяет комбинировать компоненты из разных UI-библиотек (React, Preact, Vue, Svelte, Solid и других). Основная идея Astro — минимизировать JavaScript на клиенте, предварительно рендеря страницы на сервере и подгружая только необходимую для интерактивности часть кода.

Определение в одну строку: Astro — это генератор сайтов с возможностью смешивать UI-фреймворки и отправлять на клиент минимум JS.

Для кого это подходит

  • Для сайтов, где важнее контент и скорость загрузки, но нужна локальная интерактивность.
  • Для команд, которые хотят объединить компоненты, написанные на разных фреймворках.

Установка и настройка

Если у вас уже есть проект Astro, переходите к разделу о создании стора. Если нет — создайте новый проект (требуется Node.js).

Запустите в командной строке:

npm create astro@latest  

Ответьте “y” для установки и укажите имя папки проекта. Для установки React выполните:

npx astro add react  

Установите Nano Stores для React:

npm i nanostores @nanostores/react  

Запустите проект одной из команд:

npm run dev

или

yarn run dev

или

pnpm run dev

Откройте http://localhost:3000 чтобы увидеть сайт.

Создание стора для заметок

В каталоге проекта создайте файл src/noteStore.js и добавьте в него следующий код:

import { atom } from "nanostores"  
  
export const notes = atom([])  
  
export function addNote(note) {  
  notes.set([...notes.get(), note])  
  console.log("Added note: ", note.get())  
}  

Пояснение: atom — это примитив nanostores для хранения значения. addNote добавляет новый элемент в массив заметок, избегая мутаций через spread-оператор.

Интерфейс добавления заметки (React)

Создайте src/components/NoteAddButton.jsx и вставьте этот код:

import {useState} from "react"  
import {addNote, notes} from "../noteStore"  
  
export default function NoteAdder() {  
  const [userNote, setUserNote] = useState('')  
  
  return(  
    <>  
        
  
       setUserNote(event.target.value)} />  
  
        
  
      
            {           $notes.map((note, index) => {             
  • {note}
  •           })         }       
       ) }

Примечание: В React-компоненте используется локальный state для ввода и подписка на глобальные $notes для отображения списка.

В pages/index.astro импортируйте и используйте компонент внутри тега

:

import NoteAddButton from "../components/NoteAddButton.jsx"  
---  
  
  
       
// Other code

После этого поле ввода и кнопка появятся на странице, а заметки будут сохраняться и отображаться сразу после добавления.

MacBook Pro на природе, ноутбук на фоне леса

Скриншот интерфейса заметок в браузере

Шеринг состояния между React и Solid.js

Чтобы использовать одно и то же состояние в компонентах на разных фреймворках, добавьте Solid в проект:

npx astro add solid  

Установите адаптер для Solid:

npm i nanostores @nanostores/solid  

Создайте src/components/Notes.js с таким содержимым:

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 NodeAddButton from "../components/NoteAddButton.jsx"  
import Nodes from "../components/Notes.jsx"  
---  
  
  
            
// Other code

Теперь при добавлении заметки через React-компонент она будет доступна и в Solid-компоненте без дополнительной передачи props.

Когда этот подход работает плохо

  • При очень сложной логике синхронизации между сервером и клиентом, где нужен полноценный state manager с middleware (например, Redux с кастомными миддлвэрами).
  • Если вы полагаетесь на транзакции и оптимистические обновления на стороне клиента в большом приложении с множеством источников данных.
  • Когда необходима строгая типизация на уровне всей архитектуры и централизованная система для отладки действий (action/history).

Контрпример: Для крупного SPA со сложной бизнес-логикой и большим количеством асинхронных эффектов может быть удобнее применять Redux Toolkit или MobX.

Альтернативные подходы

  • Использовать Context API React для локального шаринга внутри дерева React.
  • Redux Toolkit для централизованного хранилища с инструментами отладки и middleware.
  • Zustand как лёгкая альтернатива с минимальным API.
  • SWR или React Query для кэширования и синхронизации данных с сервером (подходит для fetch-first сценариев).

Выбор зависит от размеров проекта, потребностей в отладке и наличии нескольких UI-фреймворков.

Ментальные модели и эвристики

  • Глобальный стор хорош для состояния, которое реально глобально (настройки интерфейса, список уведомлений, общие кэши).
  • Локальный state подходит для управляемых контролов (формы, модальные окна). Сначала используйте локальный state, затем поднимайте в стор, если нужно разделение между компонентами.
  • Избегайте перфекционизма: лёгкий стор проще отрефакторить, чем монолитную систему.

Быстрый план интеграции (мини-методология)

  1. Определите набор данных, который должен жить глобально.
  2. Создайте atom/хранилища в src/stores или src/noteStore.js.
  3. Подключите адаптеры (@nanostores/react, @nanostores/solid) по потребности.
  4. Используйте client:load или client:idle в Astro для интерактивных компонентов.
  5. Напишите тесты и критерии приёмки.
  6. Проведите ревью производительности и безопасности.

Критерии приёмки

  • Компонент React успешно добавляет заметку в стор и очищает поле ввода.
  • Компонент Solid отображает добавленные заметки без перезагрузки страницы.
  • Состояние сохраняется при переходах по страницам в пределах сессии (если это требование).
  • Нет утечек памяти: подписки отписываются при размонтировании.

Контрольный список для ролей

Для разработчика:

  • Установить пакеты и проверить сборку.
  • Создать атомы для каждого логического фрагмента состояния.
  • Покрыть основные сценарии тестами.

Для дизайнера:

  • Убедиться, что компоненты корректно отображают пустое состояние и ошибки.
  • Подготовить доступные метки и состояния кнопок.

Для менеджера продукта:

  • Подтвердить набор данных, который действительно нужен глобально.
  • Утвердить требования по времени отклика интерфейса.

Совместимость и рекомендации по миграции

  • Nano Stores не привязан к конкретному фреймворку, поэтому миграция между библиотеками производится плавно: достаточно подключить соответствующий адаптер.
  • При переносе логики из локального state в стор делайте это поэтапно: сначала прочувствуйте, где данные действительно используются в нескольких местах.
  • Если требуется серверный рендеринг со стороны Astro, проверьте, какие данные должны быть сериализованы между сервером и клиентом.

Безопасность и конфиденциальность

  • Nano Stores хранит данные в памяти браузера; не используйте его для секретных ключей или персональных данных без шифрования и серверной валидации.
  • Для данных пользователя используйте серверную авторизацию и не доверяйте данным из клиента.
  • Настройте CSP и защиту от XSS, чтобы снизить риск кражи состояния через вредоносный скрипт.

Диагностика и отладка

  • Используйте console.log и инструментальные тесты для проверки обновлений стора.
  • Проверяйте отписку от подписок при размонтировании компонентов, особенно если вы вручную подписываетесь на atom.

Пример дерева принятия решений (Mermaid)

flowchart TD
  A[Нужно ли шеринговоe состояние?] -->|Да| B{Много фреймворков}
  B -->|Да| C[Использовать Nano Stores]
  B -->|Нет| D{Только React}
  D -->|Простое| E[Context API или useState]
  D -->|Сложное| F[Redux Toolkit]
  A -->|Нет| G[Локальный state в компонентах]

Тестовые случаи и приёмка

  • Добавление заметки: ввести текст, нажать Add — заметка появляется в обоих компонентах.
  • Пустой ввод: нажатие Add при пустом поле не добавляет заметку (по требованию).
  • Перезагрузка страницы: если данные не сохраняются на сервере, проверить ожидаемое поведение (обычно заметки будут потеряны).

Когда это не подходит и альтернативы

Если вам нужна история действий для undo/redo, сложные middleware или серверная синхронизация с транзакциями — рассмотрите Redux Toolkit с RTK Query или Event Sourcing-архитектуру.

Короткое резюме

  • Nano Stores — лёгкий и фреймворк-агностичный способ шаринга состояния в Astro.
  • Поддерживает React и Solid.js через официальные адаптеры.
  • Подходит для контентно-ориентированных сайтов и микросценариев интерактивности.

FAQ

Как сохранить состояние между сессиями браузера?

Nano Stores по умолчанию хранит данные в оперативной памяти. Чтобы сохранять между сессиями, синхронизируйте atom c localStorage или отправляйте данные на сервер и восстанавливайте при загрузке.

Нужно ли использовать client:load для всех интерактивных компонентов?

client:load загружает компонент при загрузке страницы. Для экономии JS используйте client:idle или client:visible, если интерактивность не нужна сразу.

Могу ли я использовать Nano Stores с другими фреймворками, например Vue?

Да. Nano Stores — фреймворк-агностичное решение. Для Vue существуют адаптеры и паттерны интеграции.


Короткое объявление: используйте Nano Stores, если нужно быстро и просто шарить состояние между компонентами на разных фреймворках в проекте Astro.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Ошибка «Сборка Windows скоро истечёт» — как исправить
Windows

Ошибка «Сборка Windows скоро истечёт» — как исправить

Скрыть языковую панель Windows 11
Windows

Скрыть языковую панель Windows 11

Управление файлами в Linux: терминал vs GUI
Linux

Управление файлами в Linux: терминал vs GUI

Несколько экземпляров Regedit в Windows 10
Windows

Несколько экземпляров Regedit в Windows 10

Отключить AirPlay на iPhone, Mac и Apple TV
Руководство

Отключить AirPlay на iPhone, Mac и Apple TV

Grammarly в React — интеграция SDK
Разработка

Grammarly в React — интеграция SDK