Reactとは
Reactは、WebページのUIをコンポーネントという部品に分けて作るためのJavaScriptライブラリです。コンポーネントは入力されたpropsや自分のstateから、画面に表示するJSXを返します。
- ViteでReactアプリを起動する
- JSXとコンポーネントで画面を分ける
- Props・State・イベントで操作に反応させる
- フォーム、API、Context、TypeScriptへ進む
ReactではDOMを直接書き換えるよりも、「このstateのときはこのUI」という関係を記述します。状態を更新するとReactが再レンダーし、画面を現在のデータに合わせます。
環境構築
Node.jsをインストールしたら、ViteでReactプロジェクトを作成します。Create React Appは現在の公式ドキュメントで新規利用が推奨されていないため、この講座ではViteを使います。
npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run devLocal: http://localhost:5173/src/main.jsxがReactをHTMLへ取り付ける入口、src/App.jsxが最初に編集するコンポーネントです。ブラウザーでURLを開き、画面が表示されれば準備完了です。
コンポーネントとJSX
Reactコンポーネントは大文字で始まるJavaScript関数です。JSXではHTMLに似た記法の中へJavaScriptの値を{}で埋め込みます。
function Greeting({ name }) {
return <h2>こんにちは、{name}さん</h2>;
}
export default function App() {
return (
<main>
<h1>Reactの練習</h1>
<Greeting name="Mika" />
</main>
);
}Reactの練習
こんにちは、MikaさんJSXでは複数の要素を一つの親要素やフラグメントで囲みます。属性はclassName、イベントはonClickのように書き、コンポーネント名は<Greeting />として呼び出します。
PropsとState
Propsは親から子へ渡す読み取り専用の値です。Stateはコンポーネントが記憶し、更新すると画面を再レンダーする値です。
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
function increment() { setCount(current => current + 1); }
return <button onClick={increment}>押した回数: {count}</button>;
}初期表示: 押した回数: 0
1回クリック: 押した回数: 1
2回クリック: 押した回数: 2直前のstateを使って更新するときは、setCount(current => current + 1)のような関数形式を使います。子で起きた操作を親へ反映するときは、親から更新関数をpropsとして渡します。
リストとフォーム
配列のmapで複数の部品を表示し、各要素には安定したkeyを指定します。入力欄の値をstateで管理する方法をcontrolled componentと呼びます。
const [text, setText] = useState('');
const [todos, setTodos] = useState([]);
function addTodo(event) {
event.preventDefault();
const value = text.trim();
if (value === '') return;
setTodos(current => [...current, { id: crypto.randomUUID(), text: value }]);
setText('');
}
return (<>
<form onSubmit={addTodo}>
<input value={text} onChange={event => setText(event.target.value)} />
<button>追加</button>
</form>
<ul>{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}</ul>
</>);空文字の扱い、送信イベントのpreventDefault、配列を直接変更しないことが重要です。keyに配列のindexだけを使うと、削除や並べ替えで入力状態が別の行へ移ることがあります。
EffectとAPI通信
useEffectは、タイマー、イベント購読、通信などReactの外にあるシステムと同期するときに使います。計算できる値をEffectで作る必要はありません。
useEffect(() => {
const controller = new AbortController();
fetch('/api/users', { signal: controller.signal })
.then(response => { if (response.ok === false) throw new Error('取得に失敗'); return response.json(); })
.then(data => { setUsers(data); setStatus('success'); })
.catch(error => { if (error.name !== 'AbortError') setStatus('error'); });
return () => controller.abort();
}, []);依存配列にはEffect内で参照するpropsやstateを含めます。通信では中断処理を用意し、古い結果が新しい画面へ反映されないようにします。firstNameとlastNameから作れるfullNameのような値は、レンダー中に計算します。
Contextと設計
深い階層へ同じ値を渡すpropsが増えたときは、Contextでテーマやログインユーザーなどを共有できます。複雑な更新手順はuseReducerでアクションと状態更新を分けます。
const ThemeContext = createContext('light');
function Button() {
const theme = useContext(ThemeContext);
return <button className={`button-${theme}`}>保存</button>;
}
function App() {
return <ThemeContext value="dark"><Button /></ThemeContext>;
}Contextは何でも入れるグローバル変数ではありません。まずstateの所有者を決め、propsで渡すほうが読みやすい場合はその方法を選びます。
次に学ぶこと
フォームとAPI通信を組み合わせた小さなアプリを作り、練習問題で理解を確認しましょう。その後、TypeScriptでpropsやAPIデータの型を付け、Next.jsでルーティングやサーバー処理へ進みます。
