~/VibeHandbook
免費 PDF

11 · 03

一個實戰示例:"收藏"功能

我們來端到端地做一個小功能:使用者可以把列表裡的條目標記為收藏,並看到自己收藏了多少個的計數。

切分它

我會這樣把它拆成縱向步驟:

  1. 在每個條目旁邊加一個星標按鈕(暫時什麼都不做,只是顯示出來)。
  2. 點選星標切換它的亮/滅外觀(僅狀態,不儲存)。
  3. 顯示一個反映這些切換的"★ 3 favorites"計數器。
  4. 儲存收藏,讓它在頁面重新載入後依然存在。

注意每一步都可獨立執行、可見。你在其中任何一步之後停下,都仍然擁有一個可執行的應用。

第 1 步:按鈕

一條好的提示會點明檔案、改動,以及不要碰什麼:

在 ItemCard 元件(src/components/ItemCard.jsx)中,給每張卡片的
右上角加一個星標按鈕。它應該渲染一個輪廓星標圖示。先別接上任何
點選行為——只讓它顯示出來。保持卡片其餘的佈局不變。

執行應用。看到星標了嗎?好。提交:

git add -A && git commit -m "Add star button to item cards"

第 2 步:切換狀態

讓星標按鈕在被點選時在填充和輪廓之間切換。用本地元件狀態來追蹤
它——先別儲存到任何地方。填充的星標表示已收藏。

可以把狀態(state)想成應用的短期記憶——此刻什麼是真的,比如某顆星星現在是否處於填充狀態。現在你在同時處理狀態和 UI,這很正常。(UI,即使用者介面,就是應用中人能看到、能點選的那一部分。)AI 大概會加上類似這樣的東西:

const [isFavorite, setIsFavorite] = useState(false);

<button onClick={() => setIsFavorite(!isFavorite)}>
  {isFavorite ? <StarFilled /> : <StarOutline />}
</button>

點幾下星標。它們會切換嗎?提交。

第 3 步:計數器

在條目列表頂部加一個"★ N favorites"計數器。它應該統計當前有多少
個條目的星標被填充。如果需要,把收藏狀態上提到列表元件,好讓
計數器能看到它。

這一步可能要求 AI 重構狀態所在之處——這在預料之中,而這恰恰是為什麼你要把它作為獨立的小步驟來做。執行它,切換幾個星標,看著數字變化。提交。

第 4 步:讓它持久化

把收藏持久化,讓它們能挺過頁面過載。現在先用 localStorage——每當
收藏條目 ID 的列表變化時就儲存它,並在啟動時載入它。

(localStorage 就是瀏覽器在訪客自己電腦上保留的一個小記事本,應用可以把東西記下來,重新載入之後再找回來。)重新載入頁面。還是收藏狀態嗎?你剛剛交付了一個功能,一次一個可執行的切片。

來看看這個完成的功能裡各部件是怎麼互相對話的。一次點擊向下流入狀態,螢幕從狀態重繪,而狀態被映象到儲存裡,於是它在重新載入後依然存活:

     ┌─────────────────────────────────────────────┐
     │                                              │
   點選星標                                     從狀態
     │ (事件)                                  重繪
     ▼                                              ▲
 ┌────────┐    更新      ┌─────────┐    饋送    ┌────────┐
 │   UI   │─────────────▶│  狀態   │───────────▶│   UI   │
 │ (按鈕) │              │(應用內  │            │(填充的 │
 └────────┘              │ 記憶體)   │            │ 星標 + │
                         └────┬────┘            │計數器) │
                              │ 變更時儲存      └────────┘
                              ▼
                         ┌──────────┐
                         │  儲存    │  ◀── 啟動時載入,
                         │(localSt.)│      所以它能挺過過載
                         └──────────┘

想離線閱讀?

免費下載整本書的 PDF 或 EPUB。