React 入門ガイド
目次
Reactとは?
ReactはFacebook(現Meta)が開発したJavaScriptのライブラリです。
画面のUI(ユーザーインターフェース)を作るために使います。
特徴
- 画面を「コンポーネント(部品)」に分けて作れる
- データが変わると画面が自動で更新される
- 大規模なアプリでも管理しやすい
基本用語
| 用語 | 読み方 | 意味 |
|---|---|---|
| コンポーネント | - | 画面の部品。ボタン・フォームなど再利用できる単位 |
| state | ステート | コンポーネントが持つ「状態(データ)」 |
| props | プロップス | 親コンポーネントから子コンポーネントへ渡すデータ |
| フック | - |
useState などReactの機能を使うための関数 |
| レンダリング | - | Reactが画面を描画すること |
| 再レンダリング | - | stateが変わったときに画面が再描画されること |
| DOM | ドム | ブラウザが管理するHTML要素全体のこと |
| JSX | ジェイエスエックス | JavaScriptの中にHTMLっぽい書き方ができる記法 |
| import | インポート | 他のファイルやライブラリの機能を読み込むこと |
| export | エクスポート | 自分のファイルの機能を外から使えるようにすること |
JSXとは?
JSXはJavaScriptの中にHTMLっぽい書き方ができる記法です。
Reactのコンポーネントは .jsx というファイルに書きます。
// JSXの例
function App() {
const name = '愛梨'
return (
<div>
<h1>こんにちは、{name}さん!</h1>
</div>
)
}
ポイント
-
{}の中にJavaScriptの変数や処理を書ける - HTMLの
classは JSX ではclassNameと書く - タグは必ず閉じる(
<br />のように自己閉じもOK)
コンポーネント
コンポーネントは画面の「部品」です。関数として定義します。
// コンポーネントの定義
function Button() {
return (
<button className="btn btn-primary">
クリック
</button>
)
}
// 別のコンポーネントから使う
function App() {
return (
<div>
<Button /> {/* Buttonコンポーネントを使う */}
<Button /> {/* 何度でも再利用できる */}
</div>
)
}
export default App
props
propsは親コンポーネントから子コンポーネントへデータを渡す仕組みです。
// 子コンポーネント(propsを受け取る側)
function Greeting({ name, age }) {
return (
<p>{name}さん({age}歳)、こんにちは!</p>
)
}
// 親コンポーネント(propsを渡す側)
function App() {
return (
<div>
<Greeting name="愛梨" age={20} />
<Greeting name="太郎" age={25} />
</div>
)
}
export default App
ポイント
- 文字列は
name="愛梨"のようにクォートで渡す - 数値・変数・関数は
age={20}のように{}で渡す - 関数も渡せる(イベントハンドラの受け渡しに使う)
フック一覧
フックはReactの機能を使うための関数です。
use から始まる名前がついています。
必ずコンポーネントの中で使います。
useState
何をするもの?
コンポーネントの「状態(データ)」を管理するフック。
stateが変わると画面が自動で再描画されます。
import { useState } from 'react'
function Counter() {
// [現在の値, 値を更新する関数] = useState(初期値)
const [count, setCount] = useState(0)
return (
<div>
<p>カウント:{count}</p>
{/* ボタンを押すとcountが1増える */}
<button onClick={() => setCount(count + 1)}>
増やす
</button>
</div>
)
}
export default Counter
ポイント
-
useState(初期値)の初期値は文字・数値・配列・オブジェクトなど何でもOK - 値を変えるときは必ず
setCountなどのセット関数を使う - 直接
count = 5と変えても画面は更新されない
useEffect
何をするもの?
「特定のタイミングで処理を実行する」フック。
import { useState, useEffect } from 'react'
function App() {
const [count, setCount] = useState(0)
// 第2引数(依存配列)によって実行タイミングが変わる
// パターン1:最初の1回だけ実行
useEffect(() => {
console.log('最初の1回だけ実行される')
}, [])
// パターン2:countが変わるたびに実行
useEffect(() => {
console.log('countが変わるたびに実行される')
}, [count])
// パターン3:毎回実行(依存配列なし)
useEffect(() => {
console.log('毎回実行される')
})
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>増やす</button>
</div>
)
}
export default App
よく使う用途
- ページを開いたときにデータを読み込む
- stateが変わったときにlocalStorageに保存する
- APIからデータを取得する
useMemo
何をするもの?
計算結果をキャッシュ(保存)しておくフック。
依存配列の値が変わったときだけ再計算します。
import { useState, useMemo } from 'react'
function App() {
const [numbers] = useState([1, 2, 3, 4, 5])
// numbersが変わったときだけ合計を再計算する
const total = useMemo(() => {
return numbers.reduce((sum, n) => sum + n, 0)
}, [numbers])
return <p>合計:{total}</p>
}
export default App
ポイント
- 重い計算処理に使うと効果的
- 単純な計算には使わなくてOK
-
useMemo自体もコストがかかるので使いすぎ注意
useCallback
何をするもの?
関数をキャッシュしておくフック。
依存配列の値が変わったときだけ関数を再生成します。
import { useState, useCallback } from 'react'
function App() {
const [count, setCount] = useState(0)
// countが変わったときだけhandleClickを再生成する
const handleClick = useCallback(() => {
setCount(count + 1)
}, [count])
return (
<div>
<p>{count}</p>
<button onClick={handleClick}>増やす</button>
</div>
)
}
export default App
ポイント
-
useMemoは「値」をキャッシュ、useCallbackは「関数」をキャッシュ - 子コンポーネントに関数をpropsで渡すときに効果的
useRef
何をするもの?
2つの使い方があります。
使い方1:DOM操作(HTML要素を直接触る)
import { useRef } from 'react'
function App() {
// input要素への参照を作る(最初はnull)
const inputRef = useRef(null)
const handleClick = () => {
// inputRef.current でinput要素そのものを取得
// .focus() でフォーカスを当てる
inputRef.current.focus()
}
return (
<div>
{/* ref属性でinput要素とinputRefをつなげる */}
<input type="text" ref={inputRef} />
<button onClick={handleClick}>フォーカスする</button>
</div>
)
}
export default App
使い方2:再描画しない値の保持
import { useRef } from 'react'
function App() {
// useRefで管理する値はstateと違い変わっても再描画しない
const countRef = useRef(0)
const handleClick = () => {
countRef.current += 1
console.log(countRef.current) // 値は変わるが画面は更新されない
}
return <button onClick={handleClick}>クリック</button>
}
export default App
useReducer
何をするもの?
複数の操作をまとめて管理するフック。
useState の代わりに使えますが、操作が複雑なときに向いています。
import { useReducer } from 'react'
// reducer関数:どんな操作をするか定義する
// state = 現在の状態、action = 命令
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
case 'RESET':
return 0
default:
return state
}
}
function Counter() {
// [現在の状態, 命令を送る関数] = useReducer(reducer関数, 初期値)
const [count, dispatch] = useReducer(reducer, 0)
return (
<div>
<p>{count}</p>
{/* dispatchで命令を送る */}
<button onClick={() => dispatch({ type: 'INCREMENT' })}>増やす</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>減らす</button>
<button onClick={() => dispatch({ type: 'RESET' })}>リセット</button>
</div>
)
}
export default Counter
ポイント
-
dispatch({ type: '命令名', payload: データ })で命令を送る -
payloadは命令と一緒に渡す追加データ(省略可) - 追加・削除など複数の操作がある場合は
useReducerが便利
useContext
何をするもの?
コンポーネント間でデータを共有するフック。
propsを使わずにどこからでもデータを取得できます。
import { createContext, useContext, useState } from 'react'
// コンテキストを作る
const UserContext = createContext(null)
// Providerでデータを提供する(包んだ子コンポーネント全員が使える)
function App() {
const [user] = useState({ name: '愛梨', age: 20 })
return (
<UserContext.Provider value={user}>
<Parent />
</UserContext.Provider>
)
}
function Parent() {
return <Child /> // Parentはデータを受け取らなくていい
}
function Child() {
// useContextでどこからでもデータを取得できる
const user = useContext(UserContext)
return <p>{user.name}さん({user.age}歳)</p>
}
export default App
ポイント
-
createContextでコンテキストを作る -
Providerで包んだコンポーネントがデータを使える - propsのバケツリレーをなくせる
フックまとめ
| フック | 何をする? | よく使う場面 |
|---|---|---|
useState |
状態を管理する | フォームの値、表示/非表示の切り替え |
useEffect |
タイミングで処理を実行 | データ読み込み、localStorage保存 |
useMemo |
計算結果をキャッシュ | 合計計算、フィルタリング |
useCallback |
関数をキャッシュ | 子コンポーネントに渡す関数 |
useRef |
DOM操作・値の保持 | フォーカス、前の値を保持 |
useReducer |
複数の操作をまとめる | 追加・削除など操作が多い状態管理 |
useContext |
データを共有する | ログイン情報、テーマ、グローバルな状態 |