React 入門:現代のWeb開発を支えるUIライブラリ
はじめに
Web開発の現場では、ユーザーインターフェース(UI)の作成が非常に重要です。ここでは、Reactというライブラリに焦点を当て、その役割や目的、使い方を解説します。HTML、CSS、JavaScript の基本は既にご理解いただいている前提で、これらとReactの関係にも触れていきます。React を使うことで、複雑なUIを効率的かつ再利用可能なコンポーネントとして実装できるようになります。
1. Reactとは?
Reactは、Facebook(現 Meta)が開発したオープンソースの JavaScript ライブラリです。主に以下のような特徴があります。
- コンポーネントベースの開発
アプリケーションを小さな再利用可能な部品(コンポーネント)に分割して作成します。これにより、開発効率が上がり、メンテナンスが容易になります。 - 宣言的なUI記述
状態に基づいてUIを自動的に再描画する仕組みを提供します。コードが見やすく、予測可能な動作が実現できます。 - 仮想 DOM(Virtual DOM)の利用
変更があった際、実際のDOMに反映する前に仮想DOM上で効率的に差分計算を行い、パフォーマンスを向上させます。
2. Reactを使う目的
Reactを導入する主な理由は以下の通りです。
複雑なUIの管理
従来の HTML / CSS / JavaScript だけで大規模なUIを管理すると、コードが散らばってしまい、バグが発生しやすくなります。Reactでは、UIをコンポーネント単位で管理するため、変更や再利用が容易です。
保守性の向上
コンポーネントが独立しているため、特定の部分のみを修正・テストすることができます。プロジェクトが大きくなるほど、コードの保守性は非常に重要になります。
開発効率の向上
React には豊富なエコシステム(ライブラリ、ツール、コミュニティ)があり、例えばルーティングや状態管理のためのライブラリを活用することで、開発を効率化できます。
ユーザー体験の向上
仮想DOMによる効率的なレンダリングや、コンポーネントの再利用により、ユーザーに対してスムーズなインタラクションを提供できます。
3. HTML、CSS、JavaScriptとの関係
React はあくまで JavaScript ライブラリであり、以下のように既存のWeb技術と連携して動作します。
HTML
Reactでは、JSXという拡張構文を用いてHTMLに似た記述を行います。JSXはブラウザ上でJavaScriptに変換され、実際のDOM操作を行います。つまり、Reactで書かれたコードは最終的にはHTMLとしてブラウザに描画されます。
CSS
コンポーネントごとにスタイルを管理する方法(CSS Modules、styled-components、Emotionなど)を用いて、CSS の適用範囲を限定し、スタイルの衝突を防ぎます。従来のグローバル CSS と比べ、より管理しやすいスタイル設計が可能です。
JavaScript
React は JavaScript の力を最大限に活用します。イベントハンドリングや非同期通信、ロジックの実装など、全て JavaScript で行われます。
4. Reactの基本概念
コンポーネント
Reactの基本単位はコンポーネントです。コンポーネントは再利用可能なUIの部品であり、以下のような2種類に大別されます。
関数コンポーネント
シンプルな構文で、関数として定義されるコンポーネントです。React Hooks を利用することで状態管理やライフサイクルの処理が可能です。
// 関数コンポーネントの例
import React from 'react';
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
export default Greeting;
クラスコンポーネント
クラス構文を使って定義され、ライフサイクルメソッドを利用できるコンポーネントです。現在は主に関数コンポーネントと Hooks が推奨されています。
JSX
JSXはJavaScript内でHTMLのような構文を記述するための拡張構文です。これにより、UI構造を直感的に記述することができます。
const element = <div className="container">Hello, React!</div>;
JSXはブラウザで動作する前に、Babelなどのトランスパイラを通して通常のJavaScriptに変換されます。
PropsとState
Props(プロパティ)
コンポーネント間で値を渡すための手段です。読み取り専用で、親コンポーネントから子コンポーネントへデータを流す際に使用します。
State
コンポーネント内で変化するデータを管理するための仕組みです。ユーザーの入力や非同期通信などでデータが変化する場合に、stateが更新されるとコンポーネントが再レンダリングされます。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
ライフサイクル
コンポーネントが生成・更新・破棄される一連の過程をライフサイクルと呼びます。関数コンポーネントの場合はHooks(例:useEffect)を使ってライフサイクルのタイミングに合わせた処理を行います。
5. 開発環境の構築
Reactのプロジェクトを始める際、以下のツールがよく利用されます。
Create React App
Facebookが提供する公式のスターターキットです。設定不要でReactアプリケーションをすぐに始めることができます。しかし、2022年4月を最後に更新が止まっています。
npx create-react-app my-app
cd my-app
npm start
Vite (オススメ)
最近人気が高まっているビルドツールで、超高速な開発サーバーが特徴です。React用のテンプレートも用意されており、シンプルにセットアップできます。
npm create vite@latest my-app --template react
cd my-app
npm install
npm run dev
6. 実際のコード例: Vite を使った React アプリ
Vite を使って実際に React のToDoアプリを作ってみましょう
Viteプロジェクトの作成手順
ターミナルで以下のコマンドを実行して、Vite の React テンプレートからプロジェクトを作成します。
npm create vite@latest my-vite-app --template react
実行すると以下のような画面が出てくるので、とりあえず react を選びます。
次に以下のような画面が出てくるので、今回は javascript で開発しましょう。
ちなみにSWCとは、Speedy Web Compiler のことで、Rust製の高速な JavaScript / TypeScript コンパイラです。従来、JavaScript や TypeScript のコードを変換(トランスパイル)する際には Babel がよく使われてきましたが、SWC は Babel に比べてビルド速度が非常に速いという特徴があります。
次に以下のコマンドを実行して
cd my-vite-app
以下のコマンドでライブラリをインストールしましょう
npm install
最後に以下のコマンドを実行すれば環境構築が完成です!
npm run dev
以下のような画面が出ると思うのでコマンドボタンを押しながら http の部分をクリックしてアクセスしましょう。
以下のような画面が表示されました
プロジェクト構成
以下に書いてるもの以外にも色々作られてると思いますが、とりあえず src フォルダの中身を以下のようにします。
my-vite-app/
├─ index.html
├─ package.json
├─ vite.config.js
└─ src/
├─ main.jsx
├─ App.jsx
└─ components/
├─ NewTaskInput.jsx
├─ Task.jsx
└─ TaskList.jsx
各ファイルの内容
1. src/main.jsx
エントリーポイントです。ここでReactアプリをレンダリングします。
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
2. src/App.jsx
アプリ全体の状態(Todoリストと新規タスクの入力値)を管理する親コンポーネントです。
ここから子コンポーネントに必要なデータや関数(props)を渡します。
import React, { useState } from 'react';
import NewTaskInput from './components/NewTaskInput.jsx';
import TaskList from './components/TaskList.jsx';
function App() {
// Todoリストと入力値をstateで管理
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState('');
// 新規タスクを追加する関数
const addTask = () => {
if (newTask.trim() !== '') {
const task = {
id: Date.now(),
text: newTask,
completed: false,
};
setTasks([...tasks, task]);
setNewTask('');
}
};
// タスクの完了状態を切り替える関数
const toggleTaskCompletion = (id) => {
const updatedTasks = tasks.map((task) =>
task.id === id ? { ...task, completed: !task.completed } : task
);
setTasks(updatedTasks);
};
// タスクを削除する関数
const deleteTask = (id) => {
const updatedTasks = tasks.filter((task) => task.id !== id);
setTasks(updatedTasks);
};
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1>Todo List App</h1>
{/* 新規タスク入力用コンポーネントにstateと関数をpropsで渡す */}
<NewTaskInput newTask={newTask} setNewTask={setNewTask} addTask={addTask} />
{/* タスクリスト表示コンポーネントにタスクデータと操作関数をpropsで渡す */}
<TaskList
tasks={tasks}
toggleTaskCompletion={toggleTaskCompletion}
deleteTask={deleteTask}
/>
</div>
);
}
export default App;
3. src/components/NewTaskInput.jsx
新しいタスクを入力するためのフォームコンポーネントです。
親から渡されたnewTask(入力値)、setNewTask(入力更新関数)、addTask(タスク追加関数)を利用します。
import React from 'react';
function NewTaskInput({ newTask, setNewTask, addTask }) {
return (
<div style={{ marginBottom: '20px' }}>
<input
type="text"
value={newTask}
onChange={(e) => setNewTask(e.target.value)}
placeholder="Enter new task..."
style={{ padding: '8px', fontSize: '16px', marginRight: '8px' }}
/>
<button onClick={addTask} style={{ padding: '8px 16px', fontSize: '16px' }}>
Add Task
</button>
</div>
);
}
export default NewTaskInput;
4. src/components/Task.jsx
個々のタスクを表示するコンポーネントです。
タスクオブジェクト(内容と完了状態)と、それに対する操作関数をpropsで受け取り、UI上で完了切替や削除ができるようにします。
import React from 'react';
function Task({ task, toggleTaskCompletion, deleteTask }) {
return (
<li
style={{
display: 'flex',
alignItems: 'center',
marginBottom: '10px',
textDecoration: task.completed ? 'line-through' : 'none',
}}
>
<span style={{ flexGrow: 1 }}>{task.text}</span>
<button
onClick={() => toggleTaskCompletion(task.id)}
style={{ marginRight: '8px', padding: '4px 8px' }}
>
{task.completed ? 'Undo' : 'Complete'}
</button>
<button onClick={() => deleteTask(task.id)} style={{ padding: '4px 8px' }}>
Delete
</button>
</li>
);
}
export default Task;
5. src/components/TaskList.jsx
Todoリスト全体を表示するコンポーネントです。
各タスクデータと操作関数(完了切替、削除)を子コンポーネントTaskに渡しています。
import React from 'react';
import Task from './Task.jsx';
function TaskList({ tasks, toggleTaskCompletion, deleteTask }) {
return (
<ul style={{ listStyleType: 'none', padding: 0 }}>
{tasks.map((task) => (
<Task
key={task.id}
task={task}
toggleTaskCompletion={toggleTaskCompletion}
deleteTask={deleteTask}
/>
))}
</ul>
);
}
export default TaskList;
これで先ほどのローカルホストを見てみると以下のようになっています。実際に色々todoを作ってみてください。
ここからさらにClassName
を指定して CSS でスタイリングしていくという流れが一般的です。
7. Reactを学ぶ上でのポイント
コンポーネントの再利用と分割
大規模なアプリケーションでは、UIを小さな部品に分け、必要に応じて再利用することが鍵となります。設計段階でコンポーネントの役割を明確にし、単一責任の原則を意識しましょう。
エコシステムの活用
React単体でも強力ですが、状態管理(Redux、Recoil、MobXなど)やルーティング(React Router)など、さまざまなライブラリと組み合わせることで、より高度なアプリケーションを構築できます。
開発ツールとデバッグ
ブラウザのReact Developer Toolsなど、デバッグ支援ツールを活用することで、コンポーネントの状態やツリー構造を視覚的に確認でき、開発効率が向上します。
8. まとめ
Reactは、コンポーネントベースの開発手法と宣言的なUI記述により、複雑なWebアプリケーションの構築と保守を大幅に効率化します。HTML、CSS、JavaScriptの既存の知識を活かしながら、React独自の概念(JSX、Props、State、ライフサイクルなど)を学ぶことで、よりモダンなWeb開発の手法に習熟することができます。これからReactを学ぶ皆さんは、まずはシンプルなコンポーネント作成やイベント処理から始め、徐々に大規模なアプリケーションへとスキルを広げていくと良いでしょう。
Discussion