React基礎のおさらい
// 変数の表示
const name = "Ichigo";
<h1>Hello, {name}!</h1>
// 条件表示
{isLoggedIn ? <Profile /> : <Login />}
{user.isAdmin && <AdminPanel />}
// リスト表示
{todos.map(todo =>
<li key={todo.id}>{todo.text}</li>
)}
{}
でJavaScript、key
は必須
// コンポーネント定義(大文字で開始)
function UserCard({ name, email, children }) {
return (
<div className="card">
<h3>{name}</h3>
<p>{email}</p>
{children}
</div>
);
}
// 使用
<UserCard name="Kurotsuchi Mayuri" email="m.kurotsuchi@seireitei.co.jp">
<button>編集</button>
</UserCard>
props
= 関数の引数、children
= タグの中身
// 小さいコンポーネント
function Header() { return <h1>ジョジョファンサイト</h1>; }
function Navigation() {
return (
<nav>
<a href="#home">ホーム</a>
<a href="#stands">スタンド</a>
</nav>
);
}
function Footer() { return <p>© 2025 ジョジョファンサイト</p>; }
// 合成して大きいコンポーネント
function App() {
return (
<div>
<Header />
<Navigation />
<main>メインコンテンツ</main>
<Footer />
</div>
);
}
クリック、入力などの操作を処理する方法
function GreetButton() {
const handleClick = () => {
alert('こんにちは!');
};
return (
<button onClick={handleClick}>
挨拶する
</button>
);
}
function QuickButton() {
return (
<button onClick={() => alert('クイック挨拶')}>
クリック
</button>
);
}
function InfoButton() {
const handleClick = (event) => {
console.log('クリック位置:', event.clientX, event.clientY);
console.log('ボタンテキスト:', event.target.textContent);
console.log('イベント種類:', event.type);
};
return <button onClick={handleClick}>情報</button>;
}
event.target.value
で入力値を取得
onClick
クリック処理onChange
入力値変更onFocus/onBlur
フォーカスevent.target.value
で値取得Reactで動的なUIを作る第一歩
function WelcomeMessage() {
return <h1>こんにちは!</h1>;
}
→ 常に同じ表示
名刺、看板、固定メニュー
function LikeButton() {
const [likes, setLikes] = useState(0);
return <button>♡ {likes}</button>;
}
→ ユーザー操作で変化
SNS、ショッピングカート、フォーム
const [状態変数, 更新関数] = useState(初期値);
useState(0)
→ 初期値0でいいね数を作成setLikes(likes + 1)
prev =>
を使うと前の状態に確実にアクセスできる
const result = useState(10);
console.log(result);
10
{value: 10, setValue: function}
[10, function]
function
const [user, setUser] = useState({name: '一護', age: 17});
// ageを18に変更したい
user.age = 18;
setUser({age: 18});
setUser({...user, age: 18});
setUser(user.age = 18);
const [items, setItems] = useState(['りんご', 'みかん']);
// 以下のうち、画面が更新されるのは?
items.push('ぶどう');
setItems([...items, 'ぶどう']);
items[0] = 'いちご';
console.log(items);
// 直接変更はNG
count = count + 1;
// オブジェクト直接変更もNG
shinigami.squad = 6;
// 配列直接変更もNG
members.push('新メンバー');
// セッター関数を使う
setCount(count + 1);
// 新しいオブジェクトを作る
setShinigami({...shinigami, squad: 6});
// 新しい配列を作る
setMembers([...members, '新メンバー']);
理由:Reactは参照が変わらないと再レンダリングしない。 pushやshift、popは元の配列を変更するため、Reactが変化を検知できない。
// こうすると2回実行されても安心
const doubleIncrement = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1); // +2される
};
// 長い
setIsDark(isDark ? false : true);
// シンプル
setIsDark(prev => !prev);
prev =>
を使うと前の状態に確実にアクセスできる
const [name, setName] = useState('一護');
const [age, setAge] = useState(16);
const [isOnline, setIsOnline] = useState(false);
○ 独立して更新できる
○ シンプルな更新
✗ 状態が多いと管理が大変
const [user, setUser] = useState({
name: '一護',
age: 16,
isOnline: false
});
○ 関連する状態をまとめられる
✗ 更新時にスプレッド構文が必要
✗ 一部だけ変更でも全体が再作成
useState
Reactでフォームを扱う基本を学ぶ
// uncontrolled - Reactが状態を知らない
<input type="text" />
// controlled - Reactがすべて管理
<input value={state} onChange={setState} />
form
要素をそのまま活用value
+ onChange
でReactが完全に状態管理
useRef
でDOM要素への参照を作成、ref.current
でアクセス
useState
と違って値が変わっても再レンダリングしない
state
で管理するパターンinput
の値は全部文字列!// ❌ バグのあるコード
const [age, setAge] = useState(20);
const handleChange = (e) => {
setAge(e.target.value); // value は常に文字列!
};
// 結果
console.log(age + 1); // "201"(文字列結合)
console.log(age > 18); // 文字列比較でバグる
console.log(typeof age); // "string"
value
は文字列として返される<input type="number">
でも例外なし!
const handleAgeChange = (e) => {
setAge(Number(e.target.value));
};
const handleNameChange = (e) => {
setName(e.target.value); // 文字列のまま
};
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setData(prev => ({
...prev,
[name]: type === 'checkbox' ? checked :
type === 'number' ? Number(value) :
value
}));
};
preventDefault
preventDefault()
がないとページが勝手にリロードされる
React stateを使わずに、送信時だけデータを取る方法
状況 | 推奨パターン | 理由 |
---|---|---|
リアルタイム表示 (文字数カウンター、プレビューなど) |
Controlled | stateが即座に反映 |
送信のみ (入力中は何もしない) |
FormData API | シンプル、高パフォーマンス |
バリデーション (入力チェック) |
Controlled | リアルタイムエラー表示 |
ファイルアップロード | Uncontrolled | ファイルはstate に入らない |
既存のライブラリ使用 | Uncontrolled | ライブラリがDOM操作 |
required
必須入力minlength
/maxlength
文字数制限min
/max
/step
数値の範囲・刻みtype
入力型(email, number等)pattern
正規表現マッチまずはHTML標準機能を使った基本的な検証から
<fieldset>
<legend>個人情報</legend>
<label htmlFor="user-name">名前(必須)</label>
<input
id="user-name"
type="text"
required
aria-describedby="name-error"
aria-invalid={hasError ? 'true' : 'false'}
/>
<div id="name-error" role="alert">
{error && error}
</div>
</fieldset>
// ミス1: 複数input管理でname属性がない(単一inputなら不要)
<input value={email} onChange={handleChange} />
<input value={name} onChange={handleChange} />
// ミス2: onChangeがある、value属性がない
<input name="text" onChange={handleChange} />
// ミス3: input type="number"でvalueを使う
const handleAgeChange = (e) => {
setAge(e.target.value); // 文字列のまま
};
// ミス4: checkboxでvalue使用
<input type="checkbox" checked={agree}
onChange={(e) => setState(e.target.value)} />
// ミ5: preventDefault忘れ
const handleSubmit = (e) => {
console.log('送信'); // ページリロード
};
// name属性で識別
<input name="name" value={name} onChange={handleChange} />
<input name="email" value={email} onChange={handleChange} />
// valueでcontrolled component
<input name="text" value={text} onChange={handleChange} />
// type="number"はNumber()で変換
const handleAgeChange = (e) => {
setAge(Number(e.target.value)); // 数値に変換
};
// checkboxはchecked
<input type="checkbox" checked={agree}
onChange={(e) => setState(e.target.checked)} />
// リロード防止
const handleSubmit = (e) => {
e.preventDefault();
};
function BrokenForm() {
const [name, setName] = useState('');
return (
<input
type="text"
onChange={(e) => setName(e.target.value)}
/>
);
}
onChange
が間違っているvalue
属性がない
setName
の書き方が間違いconst [data, setData] = useState({ character: '', role: 'student' });
const handleChange = (e) => {
setData(prev => ({
...prev,
[e.target.name]: e.target.value
}));
};
name
属性 + 計算プロパティで効率化今日学んだ内容を実際に使ってみよう!
基本的なフォームを作成してください
name
(テキスト) と powerLevel
(数値, 1-10000)console.log
して、フォームをクリアuseState
でフォーム状態を管理function ZanpakutoForm() {
const [zanpakuto, setZanpakuto] = useState({
name: "",
powerLevel: 1,
});
return <form>{/* 入力フィールドと送信ボタンを追加 */}</form>;
}
onClick={handleClick}
でユーザー操作をキャッチ、関数参照で渡す[state, setState] = useState(初期値)
で状態管理、更新で自動再レンダリングReact 応用①: useEffect、SPA