第216章:トースト通知の実装
この章でできるようになること 🥳
- 画面右上に「保存しました🎉」みたいな通知を出せる
- 成功✅ / 失敗❌ / 注意⚠️ / 情報ℹ️ を使い分けできる
- 「取り消す↩️」みたいなアクション付きトーストも出せる
- 非同期処理(通信っぽいやつ)に合わせて「保存中…⏳」→「完了🎉」もできる
トースト通知ってなに?🍞
ユーザーの操作に対して、ちょい控えめに結果を伝える小さな通知だよ〜📣 「保存したよ!」「エラーだよ!」を、画面を邪魔しすぎずに見せられるのがいいところ😊
※ shadcn/ui の **Toast コンポーネントは deprecated(非推奨)**になってて、今は Sonner を使うのが推しだよ〜🍞✨ (Shadcn)
全体の流れ(図でイメージ)🗺️
Step 1:Sonner を追加する 🍞➕
shadcn/ui の CLI で Sonner を追加するよ(WindowsでもOK🙆♀️)
npx shadcn@latest add sonner
これで Toaster コンポーネント(表示場所)と、toast()(出す命令)が使えるようになるよ〜✨ (Shadcn)
もしここで
lucide-reactやnext-themesが無いって怒られたら、これで入れればOKなことが多いよ👇
npm i lucide-react next-themes
(shadcn 側の Sonner 実装がアイコンやテーマ連携を使うことがあるよ〜)(Shadcn)
Step 2:<Toaster /> をアプリのどこか1箇所に置く 🏠
トーストは **「出す命令」**と **「表示する場所」**がセットだよ〜🍞
表示する場所が <Toaster />!
Vite なら、まずは App.tsx の一番下に置くのが分かりやすい👌
(ルートに置くのが推奨、って感じ!)(GitHub)
Step 3:まずは「出るだけ」やってみよ!🎉
src/App.tsx を、こんな感じにしてみてね👇(デモ用✨)
import { toast } from "sonner"
import { Toaster } from "@/components/ui/sonner"
import { Button } from "@/components/ui/button"
export default function App() {
return (
<div style={{ padding: 24 }}>
<h1>Toast デモ 🍞</h1>
<Button onClick={() => toast("保存しました✨")}>
ふつうのトースト
</Button>
{/* これが「トーストの表示場所」だよ! */}
<Toaster richColors position="top-right" />
</div>
)
}
Step 4:説明文&「取り消す」ボタン付きにする ↩️😋
トーストに **description(説明)**と **action(ボタン)**を付けられるよ✨ (Shadcn)
<Button
variant="outline"
onClick={() =>
toast("プロフィール更新したよ✨", {
description: "変更内容を反映しました〜🙌",
action: {
label: "取り消す",
onClick: () => toast("取り消したよ↩️"),
},
})
}
>
詳細つき + 取り消し
</Button>
「取り消す」が押されたら、もう1回 toast を出してもOKだよ〜😆🍞
Step 5:非同期処理に合わせて「保存中…」→「完了!」にする ⏳➡️🎉
通信みたいに時間がかかる処理は toast.promise が便利!✨ (Shadcn)
const save = async () => {
toast.promise<void>(
() => new Promise((resolve) => setTimeout(resolve, 1200)),
{
loading: "保存中…⏳",
success: "保存できたよ🎉",
error: "保存に失敗したよ😭",
}
)
}
ボタンに繋ぐならこんな感じ👇
<Button onClick={save}>保存(Promise)</Button>
よくあるつまづきポイント集 🧯😵💫
- トーストが出ない 👉
<Toaster />を置き忘れてる率が高い!🍞 - トーストが増殖する 👉
<Toaster />を複数箇所に置いちゃってるかも(1個でOK) - import の
@/が使えない 👉 プロジェクト側でパスエイリアスがまだなら、いったん相対パスでもOK!(例:./components/ui/sonner)
ミニ課題(5分)⏱️🎀
- 「コピーした📋」ボタンを作って、押したら
toast.success("コピーしたよ✨")を出す - 失敗用に
toast.error("コピーできなかった😭")も作って、2つのボタンで出し分けする - 上級(おまけ):「元に戻す↩️」アクション付きトーストも付けてみる
次の章(第217章)は カレンダー・日付選択📅だね! トーストができると、アプリが一気に“それっぽく”なるから楽しいよ〜🥰✨