Gerenciamento de Estado em Astro com Nano Stores
Ao desenvolver um aplicativo utilizando o framework Astro, uma dúvida comum é como administrar o estado da aplicação e compartilhá-lo entre diferentes componentes e frameworks. Nano Stores se destaca como uma excelente opção para este fim, dada sua compatibilidade com React, Preact, Svelte, Solid, Lit, Angular e até mesmo Vanilla JS.
Este guia demonstra como gerenciar o estado dentro de um projeto Astro. Acompanhe os passos simples para criar um aplicativo básico de anotações, utilizando Nano Stores para o gerenciamento do estado e compartilhando-o entre componentes React e Solid.js.
O Que é Astro?
O framework Astro possibilita a construção de aplicações web sobre estruturas de UI populares, como React, Preact, Vue e Svelte. Sua arquitetura é baseada em componentes, o que significa que cada página Astro é composta por diversos componentes.
Com o objetivo de otimizar o tempo de carregamento das páginas, o framework minimiza o uso de JavaScript no lado do cliente e realiza a pré-renderização das páginas no servidor.
Astro foi projetado para ser a ferramenta ideal para a publicação de sites com foco no conteúdo. Pense em blogs, landing pages, sites de notícias e outras páginas onde o conteúdo é o foco principal, em detrimento da interatividade. Para componentes que necessitam de interatividade, o framework envia apenas o JavaScript essencial para ativá-la.
Instalação e Configuração
Caso você já possua um projeto Astro em funcionamento, pode pular esta seção.
Caso contrário, será necessário criar um novo projeto Astro. O único pré-requisito é ter o Node.js instalado em seu ambiente de desenvolvimento.
Para criar um projeto Astro do zero, abra o seu prompt de comando, navegue até o diretório onde deseja criar o projeto e execute o seguinte comando:
npm create astro@latest
Responda com “y” para confirmar a instalação do Astro e forneça um nome para a pasta do seu projeto. Se encontrar dificuldades, você pode consultar o tutorial oficial de configuração do Astro.
Após a criação do projeto, execute o seguinte comando (para adicionar suporte a React):
npx astro add react
Finalmente, instale o Nano Stores para React executando:
npm i nanostores @nanostores/react
Ainda no seu terminal, navegue até a pasta raiz do projeto e inicie o aplicativo com um dos seguintes comandos (dependendo do seu gerenciador de pacotes):
npm run dev
Ou:
yarn run dev
Ou:
pnpm run dev
Acesse http://localhost:3000 em seu navegador para visualizar uma prévia do seu site.
Com seu projeto Astro configurado, o próximo passo é criar um armazenamento para os dados da aplicação.
Criando o Armazenamento de Notas
Crie um arquivo chamado noteStore.js
dentro do diretório /src
na raiz do seu projeto. Dentro deste arquivo, utilize a função atom()
do Nano Stores para criar um armazenamento de notas:
import { atom } from "nanostores" export const notes = atom([]) export function addNote(note) { notes.set([...notes.get(), note]) console.log("Added note: ", note.get()) }
A função addNote()
recebe uma nota como argumento e a armazena no armazenamento de notas. Ela emprega o operador spread para evitar a mutação direta dos dados, copiando o array existente antes de adicionar a nova nota.
Construindo a Interface do Aplicativo de Anotações
A interface do usuário consistirá em um campo de entrada para coletar a nota e um botão que, ao ser acionado, adiciona a nota ao armazenamento.
Dentro do diretório src/components
, crie um novo arquivo chamado NoteAddButton.jsx
e insira o seguinte código:
import {useState} from "react" import {addNote, notes} from "../noteStore" export default function NoteAdder() { const [userNote, setUserNote] = useState('') return( <> <label htmlFor="note">Adicionar uma nota: </label> <input type="text" name="note" id="note" onChange={(event) => setUserNote(event.target.value)} /> <button onClick={() => addNote(userNote)}>Adicionar</button> <ul> { $notes.map((note, index) => { <li key={index}>{note}</li> }) } </ul> </> ) }
Este código atualiza o estado do componente conforme o usuário digita na entrada. Ao clicar no botão, a nota é armazenada no armazenamento e também é exibida na lista abaixo. Desta forma, a nota aparece na página logo após o clique no botão “Adicionar”.
Agora, no arquivo pages/index.astro
, você precisa importar o componente NoteAddButton
e utilizá-lo dentro das tags <main>
:
import NoteAddButton from "../components/NoteAddButton.jsx" --- <Layout title="Bem-vindo ao Astro."> <main> <NoteAddButton client:load /> </main> </Layout>
Ao retornar ao navegador, você verá o campo de entrada e o botão renderizados na página. Insira algo no campo e clique no botão “Adicionar”. A nota aparecerá imediatamente na página e persistirá mesmo após a atualização do navegador.
Compartilhando o Estado Entre Dois Frameworks
Suponha que você queira compartilhar o estado entre React e Solid.js. O primeiro passo é adicionar o suporte a Solid ao seu projeto, executando o comando:
npx astro add solid
Em seguida, adicione o Nano Stores para Solid.js com o comando:
npm i nanostores @nanostores/solid
Para criar a interface em Solid.js, acesse o diretório src/components
e crie um novo arquivo chamado Notes.js
. Dentro deste arquivo, crie o componente Notes
:
import {useStore} from "@nanostores/solid" import {notes} from "../noteStore" import {For} from "solid-js" export default function Notes() { const $notes = useStore(notes) return( <> <h1>Minhas notas</h1> <ul> <For each={notes()} > {(note) => <li>{note}</li>} </For> </ul> </> ) }
Neste arquivo, você importa o armazenamento de notas, itera sobre cada nota e a exibe na página.
Para exibir o componente Notes
criado com Solid.js, acesse novamente o arquivo pages/index.astro
, importe o componente NoteAddButton
e o novo componente Notes
, usando-os dentro das tags <main>
:
import NodeAddButton from "../components/NoteAddButton.jsx" import Notes from "../components/Notes.jsx" --- <Layout title="Bem-vindo ao Astro."> <main> <NoteAddButton client:load /> <Notes client:load /> </main> </Layout>
Agora, retorne ao navegador, digite algo no campo de entrada e clique no botão “Adicionar”. A nota aparecerá tanto no componente React quanto no componente Solid.js, e persistirá entre as renderizações.
Outras Funcionalidades do Astro
Através dessas técnicas, você consegue gerenciar o estado em sua aplicação Astro e compartilhá-lo entre componentes e diferentes frameworks. Astro oferece também muitos outros recursos valiosos, como a coleta de dados, a minificação de HTML e a renderização paralela.