Gerencie o Estado em Aplicativos Astro com Nano Stores: Guia Completo

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.