如何管理 Astro 应用程序中的状态

在 Astro 框架中管理状态的有效方法

当您使用 Astro 框架构建应用时,状态管理和跨组件以及框架共享状态是至关重要的。 Nano Stores 是 Astro 的优秀状态管理工具,它能无缝兼容 React、Preact、Svelte、Solid、Lit、Angular 以及原生 JavaScript。

本文将深入探讨如何在 Astro 项目中有效地管理状态。我们将通过创建一个简单的笔记应用示例,演示如何利用 Nano Stores 进行状态管理,并在 React 和 Solid.js 组件之间共享状态。

Astro 框架简介

Astro 是一个强大的 Web 应用框架,它允许开发者在流行的 UI 框架(如 React、Preact、Vue 或 Svelte)之上构建应用。Astro 采用组件化架构,每个页面都由多个组件构成。

为了优化页面加载速度,Astro 框架尽可能减少客户端 JavaScript 的使用,并在服务器端预渲染页面。

Astro 的设计目标是成为发布内容驱动型网站的理想选择,例如博客、着陆页、新闻网站以及其他以内容为核心而非交互的应用。对于那些需要交互的组件,框架会智能地只发送最少量的必要 JavaScript 代码来启用交互功能。

安装与配置

如果您已有一个运行中的 Astro 项目,请跳过此部分。

如果您还没有 Astro 项目,则需要创建一个。前提是您的本地开发计算机上已安装 Node.js

要创建一个全新的 Astro 项目,请打开终端或命令提示符,导航到您希望创建项目的目录,然后运行以下命令:

npm create astro@latest

输入 “y” 确认安装 Astro,并为项目文件夹指定一个名称。如果您在设置过程中遇到任何问题,可以参考 Astro 的 官方设置教程

项目创建完成后,执行以下命令(此命令将 React 添加到您的项目中):

npx astro add react

最后,通过运行以下命令来安装 Nano Stores for React:

npm i nanostores @nanostores/react

在终端中,切换到项目根目录,并使用以下命令之一启动应用(具体取决于您使用的包管理器):

npm run dev

或者:

yarn run dev

或者:

pnpm run dev

在 Web 浏览器中访问 http://localhost:3000 来预览您的网站。

现在您的 Astro 项目已经设置完成,下一步是为应用程序数据创建存储。

创建笔记存储

在应用根目录的 /src 文件夹中,创建一个名为 noteStore.js 的文件。在此文件中,使用 nanostores 中的 atom() 函数创建笔记存储:

import { atom } from "nanostores"

export const notes = atom([])

export function addNote(note) {
  notes.set([...notes.get(), note])
  console.log("Added note: ", note.get())
}

addNote() 函数接受一个笔记作为参数,并将其存储到笔记存储中。它使用展开运算符(复制 JavaScript 对象的简写方式)来避免数据突变。

创建笔记应用的用户界面

用户界面将包含一个输入框,用于接收笔记,以及一个按钮,点击后将笔记添加到存储中。

src/components 文件夹中,创建一个名为 NoteAddButton.jsx 的新文件。然后将以下代码粘贴到文件中:

import {useState} from "react"
import {addNote, notes} from "../noteStore"

export default function NoteAdder() {
  const [userNote, setUserNote] = useState('')

  return(
    <>
      <label htmlFor="note">Add a note: </label>
      <input type="text" name="note" id="note"
        onChange={(event) => setUserNote(event.target.value)} />
      <button onClick={() => addNote(userNote)}>Add</button>
      <ul>
        {
          $notes.map((note, index) => {
            <li key={index}>{note}</li>
          })
        }
      </ul>
    </>
  )
}

这段代码会将您在输入框中输入的笔记添加到组件的状态中。当您点击按钮时,它将笔记保存到存储中。此外,它还会从存储中获取笔记并将其显示在无序列表中。通过这种方式,点击“添加”按钮后,笔记将立即显示在页面上。

现在,在 pages/index.astro 文件中,您需要导入 NoteAddButton 组件,并在 <main> 标签中使用它:

import NoteAddButton from "../components/NoteAddButton.jsx"
---
<Layout title="Welcome to Astro.">
  <main>
    <NoteAddButton client:load />
  </main>
</Layout>

现在,如果您返回浏览器,您会看到页面上呈现的输入框和按钮。在输入框中输入一些内容,然后点击“添加”按钮。笔记将立即显示在页面上,并且即使您刷新浏览器也会保留在页面上。

在两个框架之间共享状态

假设您希望在 React 和 Solid.js 之间共享状态。首先,您需要通过运行以下命令将 Solid 添加到您的项目中:

npx astro add solid

接下来,通过运行以下命令添加 Solid.js 的 Nano Store:

npm i nanostores @nanostores/solid

要在 Solid.js 中创建 UI,请转到 src/components 文件夹,创建一个名为 Notes.js 的新文件。打开该文件,并在其中创建 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>My notes</h1>
      <ul>
        <For each={notes()}>
          {(note) => <li>{note}</li>}
        </For>
      </ul>
    </>
  )
}

在此文件中,您从存储中导入笔记,循环遍历每个笔记,并在页面上显示它们。

要显示使用 Solid.js 创建的上述 Note 组件,只需转到 pages/index.astro 文件,导入 NoteAddButtonNotes 组件,并在 <main> 标签中使用它们:

import NodeAddButton from "../components/NoteAddButton.jsx"
import Notes from "../components/Notes.jsx"
---
<Layout title="Welcome to Astro.">
  <main>
    <NoteAddButton client:load />
    <Notes client:load />
  </main>
</Layout>

现在返回浏览器,在输入框中输入一些内容,然后点击“添加”按钮。笔记将显示在页面上,并在渲染之间保持持久性。

Astro 的其他新特性

通过这些技术,您可以轻松管理 Astro 应用内部的状态,并在组件和框架之间共享状态。此外,Astro 还具有许多其他有用的功能,如数据收集、HTML 压缩和并行渲染等。