Reactの基本
Reactとは?
Reactは、Facebookによって2013年にリリースされたフロントエンドライブラリで、主にユーザーインターフェース (UI) の構築に使われます。Reactの特徴は、「コンポーネント指向の設計」を採用していることです。
この設計により、UIを小さな再利用可能なパーツに分割し、複雑なアプリケーションを効率的に管理できるようにします。
歴史
Reactは、Facebookが自身のウェブサービスのパフォーマンス問題を解決するために開発したライブラリです。
当初、Facebookのニュースフィードなどでの動作が重く、開発者はUIを効率的に更新する仕組みを必要としていました。Reactは、Virtual DOMという仕組みを使い、実際のDOMを操作する前に変更を仮想的にシミュレーションし、最小限の変更だけを行うことでパフォーマンスを大幅に改善しました。
また、Reactの人気が高まった要因として、シングルページアプリケーション (SPA) の普及が挙げられます。Reactは、ページ遷移を伴わない動的なウェブアプリケーションに適しており、多くの企業や開発者が採用するようになりました。
コンポーネント指向の設計
Reactの中心的な考え方は「コンポーネント指向の設計」です。これは、アプリケーションのUIを「コンポーネント」と呼ばれる小さなパーツに分割し、再利用可能な部品として組み立てるというアプローチです。
- 再利用可能: コンポーネントは他の部分でも使い回すことができ、コードの重複を避けることができます。
- 独立性: 各コンポーネントは他の部分に影響を与えずに動作し、変更が容易です。
- 状態管理: コンポーネントはそれ自身で状態 (
state
) を持ち、状態に基づいて動的にUIを変更することができます。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
上記のコードでは、Welcome
というコンポーネントを定義し、App
コンポーネント内で複数回呼び出しています。これにより、同じ構造を持つUIパーツを効率的に生成できます。
JSXについて
JSX (JavaScript XML) は、Reactのコンポーネントを記述するための拡張構文です。JavaScript内にHTMLに似た記法を埋め込むことができるため、UIの構築が直感的になります。JSXを使うと、JavaScriptでHTML構造を生成するコードを書くよりも、視覚的にわかりやすいコードが作成できます。
const element = <h1>Hello, world!</h1>;
この例は、HTMLのように見えますが、実際にはJavaScriptコードです。このelement
変数は、JSXを使って作られたReactの要素です。
- 要素を返す: JSXを使ってUI要素を関数から返すことができます。
- JavaScript式の埋め込み: JSX内にJavaScript式を
{}
で埋め込むことができます。
const name = 'Sara';
const element = <h1>Hello, {name}</h1>;
- 属性の設定: JSXではHTML属性をJavaScriptのオブジェクトのように扱い、カスタム属性も定義可能です。
const element = <img src={user.avatarUrl} alt="User avatar" />;
- 子要素の設定: コンポーネントに複数の子要素を含めることができ、複雑なレイアウトを簡単に構築できます。
Reactコンポーネントの基礎
Functional ComponentsとClass Components: 両者の違いと使い分け
Reactにはコンポーネントを作成するための2つの主要な方法があります。Functional Components(関数コンポーネント)とClass Components(クラスコンポーネント)です。それぞれの違いと使い分けについて解説します。
Functional Components
Functional ComponentsはシンプルなJavaScriptの関数です。引数として受け取ったprops
を使ってUIを定義し、描画します。Hooksが導入される前は、Functional Componentsはステート管理やライフサイクルメソッドを使うことができない、いわば"軽量"なコンポーネントとして使われていました。
props
を受け取り、JSXを返すシンプルな関数。- Hooksの導入により、ステートや副作用(Side Effects)の処理が可能になった。
- 関数型プログラミングに適しており、シンプルかつパフォーマンスに優れる。
const Greeting = (props) => {
return <h1>Hello, {props.name}!</h1>;
};
Class Components
Class ComponentsはReactが以前からサポートしているクラスベースのコンポーネントです。React.Componentを継承し、render
メソッドを定義する必要があります。ステートの管理やライフサイクルメソッド(componentDidMount
、componentDidUpdate
など)を使うことができます。
- ステートやライフサイクルメソッドを標準で持っている。
- Reactの古いバージョンでは主要なコンポーネント作成方法だったが、現在はFunctional Components + Hooksに移行する傾向が強い。
- より多くのコードを必要とするため、やや冗長になりがち。
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
使い分け
現在、React開発ではFunctional Componentsが推奨されています。Hooksにより、Functional Componentsでもステート管理やライフサイクルメソッドを利用できるようになり、Class Componentsを使う必要が減少しました。特に新しいプロジェクトでは、Functional Componentsをベースにするのが一般的です。
Reactフックの基礎
フックとは何か?
React v16.8で導入された「フック」は、クラスコンポーネントを使用せずに、関数コンポーネント内で状態やライフサイクルのロジックを扱うための機能です。
従来、Reactではコンポーネントの状態管理や副作用の処理を行うためにクラスコンポーネントが必要でしたが、フックの登場により、これらの機能をよりシンプルで直感的な関数コンポーネントで実現できるようになりました。
フックには多くの種類がありますが、特に重要なのは「useState
」と「useEffect
」です。これらはReactアプリの中核となる機能であり、状態管理や副作用の制御を効率的に行うことができます。
useStateフック: ローカルステートの管理と、ステート更新の仕組み
useState
フックは、関数コンポーネント内で状態(ステート)を管理するためのフックです。クラスコンポーネントでのthis.state
やthis.setState
と同じ役割を果たしますが、よりシンプルに使うことができます。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>現在のカウント: {count}</p>
<button onClick={() => setCount(count + 1)}>
カウントを増やす
</button>
</div>
);
}
上記の例では、useState
は初期値0
を引数に取り、count
という現在の状態と、その状態を更新するための関数setCount
を返します。setCount
関数を使うことで、状態を更新するたびにコンポーネントが再レンダリングされ、新しい状態が反映されます。
ステート更新の注意点
ステートの更新は非同期的に行われるため、複数の更新が競合する場合や、前の状態を基に新しい状態を計算する必要がある場合は、関数を引数に取る形式でsetState
を使用するのが推奨されます。
setCount(prevCount => prevCount + 1);
useEffectフック: 副作用の管理(データフェッチ、DOM操作、タイマーなど)
useEffect
フックは、コンポーネント内で副作用を扱うために使われます。副作用とは、状態の変更以外に発生する処理、例えばデータのフェッチやDOMの操作、タイマーの設定などを指します。クラスコンポーネントにおけるcomponentDidMount
、componentDidUpdate
、componentWillUnmount
に相当する機能を提供します。
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<div>
{data ? <p>{data.title}</p> : <p>データを取得中...</p>}
</div>
);
}
この例では、useEffect
はコンポーネントが初めてレンダリングされた際にデータをフェッチし、取得したデータを状態にセットしています。useEffect
の第2引数に空の依存配列([]
)を渡すことで、この副作用は一度だけ実行されます。
useEffectを使ったライフサイクル管理
useEffect
は、関数コンポーネントのライフサイクルに対応した処理を実装するのに非常に便利です。第2引数に依存配列を渡すことで、特定の状態やプロパティが変化したときのみ副作用を実行させることができます。
- コンポーネントのマウント時: 第2引数に空配列を渡すことで、コンポーネントが初めてレンダリングされたときに一度だけ副作用を実行。
- コンポーネントのアンマウント時: 副作用内でクリーンアップ関数を返すことで、コンポーネントのアンマウント時にクリーンアップ処理を実行。
useEffect(() => {
console.log('コンポーネントがマウントされました');
return () => {
console.log('コンポーネントがアンマウントされました');
};
}, []);
useEffectの依存配列とその重要性
useEffect
の第2引数として渡す「依存配列」は、副作用がいつ実行されるかを制御する重要な役割を果たします。配列内に指定した値(状態やプロパティ)が変わるたびにuseEffect
が再実行される仕組みです。
useEffect(() => {
console.log('カウントが更新されました:', count);
}, [count]);
この場合、count
が変化するたびに副作用が実行されます。依存配列を正しく設定しないと、必要以上に副作用が発生してパフォーマンスに悪影響を及ぼしたり、逆に実行されるべきタイミングで実行されなかったりする可能性があります。
- 依存配列が空の場合: 副作用はコンポーネントのマウント時に一度だけ実行される。
- 依存配列が指定された場合: 指定された依存関係が変化するたびに副作用が実行される。
- 依存配列がない場合: 毎回レンダリングごとに副作用が実行される。