この記事は、職場の研修を終えて数か月のプログラミング初心者がReactを使用したコードの修正を経てつまづいた部分を備忘録として書いたものです。
「なんとなく動くけれど、何をしているのかが曖昧」という状態を少しでも抜け出すために学んだことを整理してみました。
初心者ですので、誤りがありましたらご指摘いただけますと幸いです。
そもそも React とは何か
React とは「ユーザーインターフェース(UI)を作るためのJavaScriptライブラリ」です。あくまで「画面を作る」ことに特化しています。
従来の JavaScript との一番の違いは、「宣言的にUIを書く」ということです。
初心者の私はまずここでつまずきました。宣言的というのは直感的に理解しづらいので具体的に説明していきます。
従来の JavaScript
従来の JavaScript は 命令的(Imperative) な書き方をします。
例:
<p id="count">0</p>
<button onclick="increment()">+1</button>
let count = 0;
function increment() {
count++;
document.getElementById("count").textContent = count;
}
ここでは
- データを更新
- DOM要素を取得・更新
- 画面を書き換え
のように画面をどう更新するか(手順)を命令しています。
これらの処理は開発者が実装しなければなりません。
React
一方、先ほどのコードを React で書くとこうなります。
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
+1
</button>
</>
);
}
ここでは
- state(状態)を更新
- コンポーネントが再実行される
- React が仮想DOMを比較して差分を計算する
- 必要な部分だけ実際のDOMを更新する
- 画面を更新
という流れで処理が行われます。
ただし React では、開発者が state を更新するだけで、DOMの更新は React が内部で自動的に行います。
このように React では、
「どう画面を更新するか」ではなく
「状態がこうなら画面はこうなる」という完成形を定義します。
この書き方を 宣言的(Declarative)UI と呼びます。
なぜ React はこの設計なのか
では、この React の特徴にはどのようなメリットがあるのでしょうか。
React を使わずに大規模な開発を行う場合、データを更新したあと、必要なDOMを1つずつ更新しなければなりません。これは更新漏れやバグ等を引き起こす可能性があります。
一方、React を使うと開発者がデータを更新するだけで React がUIを再計算し、必要なDOM更新を自動で行います。そのおかげで、開発がより簡単に、スピーディーになります。
React の基本概念
React を利用するうえで、頻出の基本的な概念を簡単に整理します。
1. Component(コンポーネント)
React ではUIをコンポーネントという部品の単位で作ります。
ボタン、ヘッダー、フッター、リストなどをそれぞれ独立した部品として作り、それらを組み合わせて画面を構成します。
作成したコンポーネントは、複数の画面や場所で繰り返し利用できます。
このように部品として分けて作ることで、
- 同じUIを簡単に再利用できる
- デザインの統一を保ちやすい
- コードの見通しがよくなり、開発や保守がしやすくなる
といったメリットがあります。
2. props(プロップス)
props は、親コンポーネントから子コンポーネントへデータを渡す仕組みです。
React ではコンポーネントが独立した部品として作られるため、別のコンポーネントに値を渡す必要があります。そのときに使うのが props です。
例:
function Greeting(props) {
return <p>Hello {props.name}</p>;
}
ここで子コンポーネントは name という値を受け取って表示します。
その値を渡すのが以下のような親コンポーネントです。
function App() {
return (
<div>
<Greeting name="Taro" />
<Greeting name="Hanako" />
</div>
);
}
この name="Taro" の部分が props として子コンポーネントに渡されます。
その結果、画面上の表示は以下のようになります。
Hello Taro
Hello Hanako
このように props を使うことで、同じコンポーネントでも渡すデータによって表示内容を変えることができます。
なお、props は基本的に読み取り専用であり、子コンポーネント側で変更することはできません。
3. state(ステート)
state は、コンポーネントが内部で持つ状態 のことです。
フォームの入力内容 や モーダルが開いているかどうか など、ユーザーの操作によって変化する「状態」を state として管理します。
state が変更されると React は自動的にUIを再描画するため、状態と画面表示を同期させることができます。
前章で例に挙げたこちらのカウンターのコードも state が使われていました。
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
+1
</button>
</>
);
}
このコードでは、count という state を管理しています。
ボタンを押すと setCount() が呼ばれ、state が更新されます。
そして state が更新されると、React が自動的にコンポーネントを再描画し、画面の表示も更新されます。
props は「親コンポーネントから渡されるデータ」ですが、
state は「コンポーネント自身が持つデータ」です。
4. Hooks(フックス)
React の関数コンポーネントでは、state を扱うために Hooks という仕組みを使用します。
Hooks を使うことで、関数コンポーネントでも状態管理や副作用の処理を行うことができます。
React にはいくつかの Hooks がありますが、私の経験上その中でも特によく使っていたのが次の2つです。
- useState:state(状態)を管理する
- useEffect:副作用(データ取得や処理の実行など)を扱う
それぞれを詳しく説明していきます。
useState
useState は、関数コンポーネントで state を管理するための Hook です。
state の説明で挙げたカウンターのコードでも以下のような形で登場していました。
const [count, setCount] = useState(0);
ここで、それぞれの意味は次の通りです。
- count:現在の状態(値)
- setCount:状態を更新する関数
- 0:初期値
実際の動きは以下のようになります。
- コンポーネントが最初に表示される
- count の値は 0 になる
- setCount() を使うと値を更新できる
先ほどの例では setCount(count + 1) となるので、
これを実行すると count は 0 → 1 → 2 → 3 ... のように更新されます。
そして state が更新されると、React はコンポーネントを再レンダリングし、画面の表示も自動的に更新されます。
useEffect
useEffect は、コンポーネントの画面描画が完了した後や、特定の値が変わったときに処理を実行するための Hook です。
例えば、次のような処理を行うときによく使われます。
- APIからデータを取得する
- 画面表示後にログを出力する
- 特定の state が変わったときに処理を実行する
例:
import { useEffect } from "react";
function Sample() {
useEffect(() => {
console.log("コンポーネントが表示されました");
}, []);
return <p>Hello</p>;
}
このコンポーネントが実行されると、
return <p>Hello</p> をもとに UI が生成され、画面に描画されます。
その画面描画が完了した後に useEffect の処理が実行されます。
つまり、まず画面上に Hello と表示され、
その後 コンポーネントが表示されました というログが出るのです。
また、第二引数の [] は「依存配列」と呼ばれ、この配列に指定した値が変化したときに useEffect が再実行されます。
| 依存配列 | 意味 |
|---|---|
| [] | 初回表示時だけ実行 |
| [count] | countが変わるたび実行 |
| 省略 | 毎回の再レンダリングで実行 |
まとめ
この記事では、React の基本的な考え方とよく使われる仕組みについて整理しました。
React では、UIをコンポーネントという部品単位で作り、それらを組み合わせて画面を構築します。
コンポーネント同士でデータを受け渡す仕組みが props、コンポーネント自身が持つ状態が state です。
また、関数コンポーネントで状態管理や処理の実行を行うための仕組みが Hooks であり、特に useState や useEffect は実務でもよく使われます。
他にもいろいろな Hooks がありますので、また別の機会にまとめてみたいと思います。