Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Tokyoのハンズオンに飛び込んでみた話

Avatar for sai-lens sai-lens
September 29, 2025

React Tokyoのハンズオンに飛び込んでみた話

Avatar for sai-lens

sai-lens

September 29, 2025
Tweet

Other Decks in Technology

Transcript

  1. 開催日: 9/7(日) 会場: エアウォーターの森 講師: Daishi Katoさん Teruhisa さん 参加者:

    少人数(私+3人) フレームワーク作者から直接 学べる貴重な場! イベント概要 3
  2. 1. 在庫を追加 → JSONが更新される 2. 一覧が最新に反映される 3. 削除 → 即座に反映

    フロントエンドとバックエンドの役割分担が腑に落ちた! 動作デモ 8
  3. import "/styles/globals.css"; import InventoryList from "../components/InventoryList"; import NewItemForm from "../components/NewItemForm";

    import { readItems } from "../lib/items"; export default async function HomePage() { const items = await readItems(); return ( <main className="grid"> <InventoryList items={items} /> <NewItemForm /> </main> ); } export const getConfig = async () => ({ render: "dynamic" } as const); コード紹介(1/4) src/pages/index.tsx 9
  4. import { addItemServer, readItems, deleteItemServer, type Item } from "../../lib/items";

    . . if (req.method === "GET") { const items = await readItems(); return new Response(JSON.stringify(items), { headers: { "content-type": "application/json" }; if (req.method === "POST") {...}; return new Response(JSON.stringify(await addItemServer(item)), { headers: { "content-type": "application/json" } }); } if (req.method === "DELETE") {...}; return new Response(JSON.stringify(await deleteItemServer(id)), { headers: { "content-type": "application/json" } }); } . . コード紹介(2/4)データの窓口となる api/items.ts 10
  5. export async function readItems() { ... } export async function

    addItemServer(item) { ... } export async function deleteItemServer(id) { ... } コード紹介(3/4)サーバーでデータを扱う lib/items.ts 11
  6. 'use client'; export default function NewItemForm() { const onAdd =

    async () => { await fetch("/api/items", { method: "POST", body: ... }); location.reload(); }; return <button onClick={onAdd}>追加</button>; } クライアントは「受付窓口」 コード紹介(4/4)クライアントのフォーム NewItemForm.tsx 12