今さら訊けないReactの基本メモ
やること
モダンなフロントエンド開発で大事そうなReactの基本をまとめておく
参考文献
コンポーネント
コンポーネントとは何か
コンポーネントはUIの再利用可能な構成部品であり、マークアップ、CSS、JavaScriptを一つにまとめたものです。例えばボタン、フォーム、ダイアログ、アバターなど、画面上のあらゆるUI要素をコンポーネントとして定義できます。
コンポーネントの定義方法
Reactのコンポーネントは基本的にJavaScript関数として定義します。ただし、通常の関数とは異なり、名前は常に大文字で始める(例:Profile、Button、Navigation)、JSXマークアップをreturnするといった特徴があります。
function Greeting() {
return (
<h1>こんにちは、Reactの世界へ!</h1>
);
}
export default Greeting;
Propsの使用方法
Reactコンポーネントは互いにやりとりをする際に「props」というものを使います。propsは親コンポーネントから子コンポーネントに情報を渡すための仕組みです。HTML属性に似ていますが、オブジェクト、配列、関数など、あらゆるJavaScriptの値を渡すことができます。
例えば、次のようにして親コンポーネントでpropsを渡し、子コンポーネントでは、関数の引数としてpropsを受け取ります。
// 親コンポーネント
function Profile() {
return (
<Avatar
person={{ name: 'micky', imageId: 'image_01' }}
size={100}
/>
);
}
// 子コンポーネント
function Avatar({ person, size }) {
// ここでpersonオブジェクトとsizeを使用
return (
<img
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
);
}
State(状態)の管理
コンポーネントがユーザー操作に反応して変化する場合、useStateフックを使用して状態(state)を管理します。stateはコンポーネントのメモリのようなもので、ユーザー操作などによって変化する値を保持します。
import { useState } from 'react';
function Counter() {
// count: 現在の状態値
// setCount: 状態を更新するための関数
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
増加
</button>
</div>
);
}
イベント処理
イベント処理は、ユーザーのインタラクション(クリック、入力、ホバーなど)に応答するための仕組みです。Reactでは、JSXにイベントハンドラを追加することで、様々なユーザーインタラクションに対応できます。イベントハンドラとは、特定のイベントが発生した時に実行される関数のことです。
イベントハンドラの記述方法
イベントハンドラは主に以下の2種類の方法があるようです。
// コンポネント内で関数を定義して渡す
function Button() {
function handleClick() {
alert('クリックされました!');
}
return <button onClick={handleClick}>クリックしてください</button>;
}
// インラインで関数を定義する
function Button() {
return <button onClick={() => alert('クリックされました!')}>クリックしてください</button>;
}
イベントハンドラとして関数を渡す際の注意点としては、関数を「渡す」のであって、「呼び出す」のではないということです。
正: <button onClick={handleClick}>
誤: <button onClick={handleClick()}>
後者の書き方だと、レンダリング時に関数が即座に実行されてしまい、クリックイベント時には実行されません。
イベント伝播
Reactでは、DOMと同様にイベントが「バブリング」または「伝播」します。つまり、子要素でイベントが発生すると、それは親要素にも伝わります。なので、イベント伝播を停止したい場合は、イベントオブジェクトのstopPropagation()メソッドを使用します
<div onClick={handleParentClick}>
親要素
<button onClick={handleChildClick}>子要素</button>
</div>
function handleChildClick(e) {
e.stopPropagation();
// 処理...
}
デフォルト動作の防止
フォーム送信などの一部のイベントには、ブラウザのデフォルト動作があります。これを防止するには、イベントオブジェクトのpreventDefault()メソッドを使用します。
function handleSubmit(e) {
e.preventDefault();
// フォーム処理...
}
再レンダリング
再レンダリングは、UIを最新の状態に保つための基本的なメカニズムで、以下の場合に再レンダリングが発生します。
・コンポーネントの初回レンダリング時
・コンポーネント自身の状態(state)が更新されたとき
・親コンポーネントが再レンダリングされたとき
・コンポーネントがpropsを受け取り、その値が変更されたとき
以下は「カウントアップ」ボタンをクリックするたびに setCount が呼び出され、コンポーネントが再レンダリングされる例です。コード内でReactは前回のレンダリング結果と今回の結果を比較し、実際に変更があった部分(この場合は数字の表示部分)だけを更新します。
function Counter() {
const [count, setCount] = useState(0);
console.log('Counter コンポーネントがレンダリングされました');
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
カウントアップ
</button>
</div>
);
}
useEffectと副作用
useEffectはReactにおける副作用を処理するためのフックです。副作用とは、レンダリング以外のタスクのことで、データフェッチングやDOMの直接操作を指します。
useEffectの基本構文
useEffectは以下のように依存配列によって挙動が異なるので、理解しておく必要があります。
// 依存配列がない場合、すべての再レンダリング後に実行
useEffect(() => {
console.log('毎回の再レンダリング後に実行');
}); // 依存配列を省略
// 空の依存配列の場合、マウント時一度だけ実行され、アンマウント時クリーンアップ関数が実行
useEffect(() => {
console.log('マウント時のみ実行');
return () => {
console.log('アンマウント時のみ実行');
};
}, []); // 空の依存配列
// 依存値を含む配列の場合、初回レンダリング時と指定した依存値countが変更されたときのみ実行
useEffect(() => {
console.log(`count が変更されました: ${count}`);
return () => {
console.log('count変更前またはアンマウント時に実行');
};
}, [count]); // count を依存値として指定
イベントリスナーの具体例
この例では初期状態として、現在のウィンドウの innerWidth と innerHeight を取得してオブジェクトとして設定し、useState フックを使用して、ウィンドウのサイズを保持する状態変数 windowSize を作成しています。その後、useEffect でイベントリスナーを設定し、コンポーネントのレンダリングを行うという流れです。
// 1. 状態(State)の設定
function WindowSizeTracker() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
// 2. useEffect によるイベントリスナーの設定
useEffect(() => {
// ハンドラー関数の定義
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
// イベントリスナーの追加
window.addEventListener('resize', handleResize);
// クリーンアップでイベントリスナーを削除
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // マウント時にのみ設定
// 3. コンポーネントのレンダリング
return (
<div>
<p>幅: {windowSize.width}px</p>
<p>高さ: {windowSize.height}px</p>
</div>
);
}
コメントなど
Reactの基本をざっくりまとめてみました。それぞれの概念はこういうもんかとわかったものの、もう少し触ってみないとよくわからんという感じですね。あと最後の方でuseEffectについて書きましたが、なるべく使わない方がいいらしい...この辺の話も次回以降記事にしていこうと思います。
Discussion