reactのApp.tsxのステップ・バイ・ステップで学習してみた。
最小のreact
|
1 2 3 |
export default function App() { return <h1>こんにちは</h1>; } |
はじめての変数
|
1 2 3 4 5 6 |
export default function App() { // はじめての変数 const message = "こんにちは!!"; // 変数の値を使う return <h1>{message}</h1>; } |
複数の変数の表示
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
export default function App() { // 変数その1 const message1 = "こんにちは!!"; // 変数その2 const message2 = "さようなら"; // Flagment(単一ルートが絶対必要) <>...</> // 複数のタグを直接returnできない。 return ( <> <h1>{message1}</h1> <h1>{message2}</h1> </> ); } |
ボタンクリックの処理
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export default function App() { // クリック関数 function handleClick() { alert("クリックされた!"); } // ボタンだけ return ( <> <button onClick={handleClick}>click me</button> </> ); } |
値の保持
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Reactから useState という機能を読み込む import { useState } from "react"; export default function App() { // const 直接代入はしない() // count 現在の値 // setCount countを変更するための関数 // number countは数値型 // 0 初期値 const [count, setCount] = useState<number>(0); // クリック関数 function handleClick() { setCount(count + 1); } // ボタン押下で関数実行 return ( <> <p>現在のカウント{count}</p> <button onClick={handleClick}>ぷらす1</button> </> ); } |
Webフォーム(空文字じゃなくなったら登録ボタンをenable)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import { useState } from "react"; export default function App() { // 入力欄の文字を管理する状態 const [name, setName] = useState<string>(""); // 入力欄の内容が変わったときに実行される処理 function handleChange(event: React.ChangeEvent<HTMLInputElement>) { setName(event.target.value); } // 登録ボタンを押したときの処理 function handleSubmit() { alert(`${name}さんを登録します`); } return ( <> <h1>ユーザー登録(空文字では登録ボタンがdisable)</h1> <input type="text" value={name} onChange={handleChange} placeholder="名前を入力してください" /> <p>入力中の名前: {name}</p> <button onClick={handleSubmit} disabled={name === ""}> 登録 </button> </> ); } |
入力途中の文字列を使って、結果をフィルタリング
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import { useState } from "react"; export default function App() { // 検索欄に入力された文字を管理する状態 const [keyword, setKeyword] = useState<string>(""); // 表示対象のユーザー一覧 const users = [ "Alice", "Alan", "Amanda", "Bob", "Brian", "Betty", "Charlie", "Chris", "Catherine", "David", "Daniel", "Diana", ]; // 大文字・小文字を区別せずに検索できるようにする const lowerKeyword = keyword.toLowerCase(); // 入力された文字を含むユーザーだけに絞り込む const filteredUsers = users.filter((user) => { return user.toLowerCase().includes(lowerKeyword); }); // 検索欄の内容が変わったときに実行される処理 function handleChange(event: React.ChangeEvent<HTMLInputElement>) { setKeyword(event.target.value); } return ( <> <h1>User Search</h1> <input type="text" value={keyword} onChange={handleChange} placeholder="Search by name" /> <p>Keyword: {keyword}</p> <ul> {filteredUsers.map((user) => ( <li key={user}>{user}</li> ))} </ul> </> ); } |
公開API(ZipCloud)を使って、郵便番号から住所を取得
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
import { useState, type ChangeEvent } from "react"; // ZipCloudから返ってくる住所1件分の型 type Address = { zipcode: string; prefcode: string; address1: string; address2: string; address3: string; kana1: string; kana2: string; kana3: string; }; // ZipCloud API全体のレスポンスの型 type ZipCloudResponse = { message: string | null; results: Address[] | null; status: number; }; export default function App() { // 郵便番号の前半3桁を管理する状態 const [zipcodeFirst, setZipcodeFirst] = useState<string>(""); // 郵便番号の後半4桁を管理する状態 const [zipcodeSecond, setZipcodeSecond] = useState<string>(""); // APIから取得した住所一覧を管理する状態 const [addresses, setAddresses] = useState<Address[]>([]); // 通信中かどうかを管理する状態 const [loading, setLoading] = useState<boolean>(false); // エラーメッセージを管理する状態 const [errorMessage, setErrorMessage] = useState<string>(""); // 郵便番号の前半3桁が変更されたときに実行される処理 function handleZipcodeFirstChange(event: ChangeEvent<HTMLInputElement>) { // 数字以外を取り除き、最大3桁までにする const value = event.target.value.replace(/\D/g, "").slice(0, 3); setZipcodeFirst(value); } // 郵便番号の後半4桁が変更されたときに実行される処理 function handleZipcodeSecondChange(event: ChangeEvent<HTMLInputElement>) { // 数字以外を取り除き、最大4桁までにする const value = event.target.value.replace(/\D/g, "").slice(0, 4); setZipcodeSecond(value); } // 郵便番号から住所を検索する処理 async function searchAddress() { // 前半3桁と後半4桁を結合して、7桁の郵便番号にする const normalizedZipcode = `${zipcodeFirst}${zipcodeSecond}`; // 前回の検索結果とエラーを一度クリアする setAddresses([]); setErrorMessage(""); // 郵便番号が7桁でなければAPIを呼ばない if (normalizedZipcode.length !== 7) { setErrorMessage("郵便番号は3桁と4桁で入力してください"); return; } try { // 通信中の状態にする setLoading(true); // ZipCloud APIを呼び出す const response = await fetch( `https://zipcloud.ibsnet.co.jp/api/search?zipcode=${normalizedZipcode}` ); // レスポンスをJSONとして受け取る const data: ZipCloudResponse = await response.json(); // API側でエラーメッセージが返ってきた場合 if (data.message) { setErrorMessage(data.message); return; } // 該当する住所がなかった場合 if (!data.results) { setErrorMessage("該当する住所がありません"); return; } // 取得した住所をstateに入れる setAddresses(data.results); } catch { // 通信そのものに失敗した場合 setErrorMessage("住所検索に失敗しました"); } finally { // 成功しても失敗しても、最後に通信中状態を解除する setLoading(false); } } return ( <> <h1>郵便番号検索</h1> <div> <input type="text" value={zipcodeFirst} onChange={handleZipcodeFirstChange} placeholder="100" /> <span> - </span> <input type="text" value={zipcodeSecond} onChange={handleZipcodeSecondChange} placeholder="0001" /> <button type="button" onClick={searchAddress} disabled={loading}> 検索 </button> </div> <p> 入力中の郵便番号: {zipcodeFirst}-{zipcodeSecond} </p> {loading && <p>検索中...</p>} {errorMessage && <p>{errorMessage}</p>} <ul> {addresses.map((address) => ( <li key={address.zipcode}> {address.zipcode}: {address.address1} {address.address2} {address.address3} </li> ))} </ul> </> ); } |