プレイグラウンド、サンドボックス、使い捨てスクリプト置き場
0

Configure Feed

Select the types of activity you want to include in your feed.

update

Kohei Watanabe (Jan 13, 2026, 2:31 PM +0900) c657e0c6 06c3e798

+24 -35
+23 -34
use-swr/src/App.tsx
··· 1 - import { type ReactNode, useState } from "react"; 1 + import { useState } from "react"; 2 2 import useSWR, { SWRConfig } from "swr"; 3 3 import "./App.css"; 4 4 5 5 const API_BASE = "https://jsonplaceholder.typicode.com"; 6 6 7 - const fetcher = (url: string) => fetch(url).then((r) => r.json()); 7 + const fetcher = (url) => fetch(url).then((r) => r.json()); 8 8 9 9 // ======================================== 10 10 // Providers: SWRのグローバル設定 11 11 // ======================================== 12 - function Providers({ children }: { children: ReactNode }) { 13 - return ( 14 - <SWRConfig value={{ fetcher, dedupingInterval: 2000 }}> 15 - {children} 16 - </SWRConfig> 17 - ); 12 + function Providers({ children }) { 13 + return <SWRConfig value={{ fetcher }}>{children}</SWRConfig>; 18 14 } 19 15 20 16 // ======================================== ··· 22 18 // - 同じuserIdで複数回使用 → キャッシュ共有を確認 23 19 // - refreshInterval で定期更新を確認 24 20 // ======================================== 25 - function UserDetail({ 26 - userId, 27 - enableRefresh = false, 28 - }: { 29 - userId: number; 30 - enableRefresh?: boolean; 31 - }) { 21 + function UserDetail({ userId, enableRefresh = false }) { 32 22 const { data, error, isLoading } = useSWR<{ 33 23 id: number; 34 24 name: string; ··· 61 51 62 52 // ======================================== 63 53 // User: キャッシュ共有と定期更新の確認 64 - // - 2つのUserDetailを並べて、2回目がキャッシュ命中で即表示されることを確認 54 + // - 2つ以上のUserDetailを並べて、2回目以降キャッシュ・ヒットで即表示されることを確認 65 55 // - URLを変更して結果の差を確認 66 56 // ======================================== 67 57 function User() { ··· 74 64 <p style={{ fontSize: "0.9rem", color: "#666" }}> 75 65 同じURLを参照する2つのコンポーネントがキャッシュを共有。 76 66 <br /> 77 - 2回目は即座に表示される(DevTools Networkで1回のみリクエスト確認)。 67 + 2回目以降は即座に表示される(DevTools Networkで1回のみリクエスト確認)。 78 68 </p> 79 69 80 70 <div ··· 205 195 > 206 196 ID: {userId} 207 197 </span> 208 - <span style={{ fontSize: "0.8rem", color: "#888" }}> 209 - ← 即座に変わる 210 - </span> 198 + <span style={{ color: "#888" }}>← 即座に変わる</span> 211 199 </div> 212 200 213 201 {isLoading ? ( ··· 242 230 // - 空文字の場合はkeyがnullになりリクエストが発生しない 243 231 // ======================================== 244 232 function Profile() { 245 - const [inputId, setInputId] = useState(""); 246 - const [submittedId, setSubmittedId] = useState<string | null>(null); 233 + // 入力中のユーザーID 234 + const [userId, setUserId] = useState(""); 235 + // 確定したユーザーID 236 + const [submittedUserId, setSubmittedUserId] = useState(""); 247 237 248 238 const { data, error, isLoading } = useSWR<{ 249 239 id: number; 250 240 name: string; 251 241 email: string; 252 242 phone: string; 253 - }>(submittedId ? `${API_BASE}/users/${submittedId}` : null); 254 - 255 - const handleSubmit = (e: React.FormEvent) => { 256 - e.preventDefault(); 257 - if (inputId.trim()) { 258 - setSubmittedId(inputId.trim()); 259 - } 260 - }; 243 + }>(submittedUserId ? `${API_BASE}/users/${submittedUserId}` : null); 261 244 262 245 return ( 263 246 <section style={{ marginBottom: "2rem" }}> ··· 268 251 (DevTools Networkで確認) 269 252 </p> 270 253 271 - <form onSubmit={handleSubmit} style={{ marginBottom: "1rem" }}> 254 + <form 255 + onSubmit={(e) => { 256 + e.preventDefault(); 257 + setSubmittedUserId(userId.trim()); 258 + }} 259 + style={{ marginBottom: "1rem" }} 260 + > 272 261 <input 273 262 type="text" 274 - value={inputId} 275 - onChange={(e) => setInputId(e.target.value)} 263 + value={userId} 264 + onChange={(e) => setUserId(e.target.value)} 276 265 placeholder="ユーザーID (1-10)" 277 266 style={{ padding: "0.5rem", marginRight: "0.5rem" }} 278 267 /> ··· 281 270 </button> 282 271 </form> 283 272 284 - {submittedId === null && ( 273 + {submittedUserId === "" && ( 285 274 <p style={{ color: "#888" }}>IDを入力して検索してください</p> 286 275 )} 287 276
+1 -1
use-swr/tsconfig.app.json
··· 17 17 "jsx": "react-jsx", 18 18 19 19 /* Linting */ 20 - "strict": true, 20 + // "strict": true, 21 21 "noUnusedLocals": true, 22 22 "noUnusedParameters": true, 23 23 "erasableSyntaxOnly": true,