Reactの使い方ガイド|初心者でもわかる基本構文と実践テクニック

JavaScript

Reactは、きれいなウェブサイトを簡単に作るためのJavaScriptのツールです。

Reactの最大の特徴は「コンポーネント」という仕組みです。これは、レゴブロックのような部品を組み合わせて画面を作る方法です。

一度作った部品は何度でも使い回せるので、効率的に開発できます。

この記事では、Reactの基本的な使い方を、実際のコード例を見ながら初心者の方にもわかりやすく説明します。

この記事で学べること

  • コンポーネントの作り方と使い方
  • データの受け渡し方法(props)
  • 画面の状態管理(state)
  • ボタンクリックなどのイベント処理
  • リスト表示と条件分岐の書き方
スポンサーリンク

Reactコンポーネントの基本を理解しよう

コンポーネントってなに?

コンポーネントとは、ウェブサイトの部品のことです。例えば:

  • ボタン:クリックできる四角い部品
  • フォーム:文字を入力する部品
  • ヘッダー:ページの上に表示される部品
  • カード:情報をまとめて表示する部品

これらの部品を組み合わせることで、完成したウェブサイトを作ります。

最初のコンポーネントを作ってみよう

簡単な挨拶を表示するコンポーネントを作ってみましょう:

function Hello(props) {
  return <h1>こんにちは、{props.name}さん!</h1>;
}

コードの説明

  • function Hello:「Hello」という名前のコンポーネントを作ります
  • props:外部から受け取るデータです
  • return:画面に表示する内容を返します
  • <h1>:大きな見出しを表示するHTMLタグです
  • {props.name}:propsの中のnameという値を表示します

JSXという書き方について

上のコードで使っている<h1>のような書き方をJSXと呼びます。

JSXの特徴

  • HTMLとほぼ同じように書けます
  • でも実際はJavaScriptのコードです
  • 必ず一つの親要素で全体を囲む必要があります

正しい書き方の例

// ✅ 正しい:divで全体を囲んでいる
function MyComponent() {
  return (
    <div>
      <h1>タイトル</h1>
      <p>説明文</p>
    </div>
  );
}

// ❌ 間違い:複数の要素が並列になっている
function MyComponent() {
  return (
    <h1>タイトル</h1>
    <p>説明文</p>
  );
}

コンポーネントはReactの基本的な仕組みです。小さな部品を作って、それを組み合わせることで大きなアプリケーションを作っていきます。

propsとstateでデータを扱おう

props:外部からデータをもらう仕組み

propsは、コンポーネントに外部から情報を渡すための仕組みです。

Helloコンポーネントの使い方

// Helloコンポーネントを呼び出して使う
<Hello name="田中" />
<Hello name="佐藤" />
<Hello name="山田" />

結果として表示される内容

こんにちは、田中さん!
こんにちは、佐藤さん!
こんにちは、山田さん!

複数のpropsを渡す例

function UserCard(props) {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>年齢:{props.age}歳</p>
      <p>職業:{props.job}</p>
    </div>
  );
}

// 使い方
<UserCard name="田中太郎" age={25} job="エンジニア" />

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)}>
        プラス1
      </button>
      <button onClick={() => setCount(count - 1)}>
        マイナス1
      </button>
      <button onClick={() => setCount(0)}>
        リセット
      </button>
    </div>
  );
}

useStateの使い方

const [変数名, 変更用の関数名] = useState(初期値);
  • count:現在の値を保存する変数
  • setCount:値を変更するための関数
  • useState(0):最初の値を0に設定

stateとpropsの違い

  • props:親コンポーネントから受け取る情報(変更できない)
  • state:コンポーネント内部で管理する情報(変更できる)

propsは外部から、stateは内部で管理することを覚えておきましょう。次は、ボタンクリックなどのイベント処理について学びます。

イベント処理とフォームを作ってみよう

ボタンクリックなどのイベントを処理する

Reactでは、ボタンクリックや文字入力などのイベントを簡単に処理できます。

基本的なイベント処理

function ButtonExample() {
  const handleClick = () => {
    alert('ボタンがクリックされました!');
  };

  return (
    <button onClick={handleClick}>
      クリックしてください
    </button>
  );
}

よく使うイベント

  • onClick:クリックされたとき
  • onChange:入力内容が変わったとき
  • onSubmit:フォームが送信されたとき
  • onMouseOver:マウスが乗ったとき

文字入力フォームを作る

ユーザーが文字を入力できるフォームを作ってみましょう:

import { useState } from 'react';

function NameForm() {
  const [name, setName] = useState('');

  const handleChange = (e) => {
    setName(e.target.value);
  };

  const handleSubmit = () => {
    alert(`入力された名前:${name}`);
  };

  return (
    <div>
      <h3>お名前を入力してください</h3>
      <input 
        type="text"
        value={name}
        onChange={handleChange}
        placeholder="名前を入力"
      />
      <button onClick={handleSubmit}>
        送信
      </button>
      <p>現在の入力:{name}</p>
    </div>
  );
}

コードの説明

  • value={name}:入力欄に表示される値をstateと連動させます
  • onChange={handleChange}:入力内容が変わるたびに関数を実行します
  • e.target.value:入力された文字を取得します

複数の入力欄を持つフォーム

もう少し複雑なフォームも作れます:

import { useState } from 'react';

function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData({
      ...formData,
      [name]: value
    });
  };

  const handleSubmit = () => {
    console.log('送信データ:', formData);
  };

  return (
    <div>
      <h3>お問い合わせフォーム</h3>
      <input
        type="text"
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="お名前"
      />
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="メールアドレス"
      />
      <textarea
        name="message"
        value={formData.message}
        onChange={handleChange}
        placeholder="メッセージ"
      />
      <button onClick={handleSubmit}>
        送信する
      </button>
    </div>
  );
}

イベント処理では、関数を作ってイベントに紐付けるだけで動作します。フォームの状態管理も、useStateを使えば簡単に実現できます。

リストの表示と条件分岐をマスターしよう

配列のデータをリスト表示する

複数のデータを一覧で表示するには、JavaScriptのmap関数を使います。

基本的なリスト表示

function FruitList() {
  const fruits = ['りんご', 'バナナ', 'ぶどう', 'みかん', 'いちご'];

  return (
    <div>
      <h3>果物リスト</h3>
      <ul>
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </div>
  );
}

オブジェクトの配列を表示する

function UserList() {
  const users = [
    { id: 1, name: '田中太郎', age: 25 },
    { id: 2, name: '佐藤花子', age: 30 },
    { id: 3, name: '山田次郎', age: 22 }
  ];

  return (
    <div>
      <h3>ユーザー一覧</h3>
      {users.map(user => (
        <div key={user.id} style={{ border: '1px solid #ccc', margin: '10px', padding: '10px' }}>
          <h4>{user.name}</h4>
          <p>年齢:{user.age}歳</p>
        </div>
      ))}
    </div>
  );
}

keyプロパティについて

  • key={index}key={user.id}は必須です
  • Reactが効率的に画面を更新するために必要です
  • 一意の値(重複しない値)を設定します

条件によって表示を変える

条件分岐を使って、状況に応じて異なる内容を表示できます。

基本的な条件分岐

import { useState } from 'react';

function LoginStatus() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  return (
    <div>
      {isLoggedIn ? (
        <div>
          <h3>ようこそ!</h3>
          <button onClick={() => setIsLoggedIn(false)}>
            ログアウト
          </button>
        </div>
      ) : (
        <div>
          <h3>ログインしてください</h3>
          <button onClick={() => setIsLoggedIn(true)}>
            ログイン
          </button>
        </div>
      )}
    </div>
  );
}

複数の条件を組み合わせる

function WeatherApp() {
  const [weather, setWeather] = useState('sunny');

  const getWeatherMessage = () => {
    if (weather === 'sunny') {
      return '☀️ 今日は晴れです!';
    } else if (weather === 'rainy') {
      return '☔ 今日は雨です。傘を忘れずに!';
    } else if (weather === 'cloudy') {
      return '☁️ 今日は曇りです。';
    } else {
      return '❄️ 今日は雪です!';
    }
  };

  return (
    <div>
      <h3>今日の天気</h3>
      <p>{getWeatherMessage()}</p>
      <button onClick={() => setWeather('sunny')}>晴れ</button>
      <button onClick={() => setWeather('rainy')}>雨</button>
      <button onClick={() => setWeather('cloudy')}>曇り</button>
      <button onClick={() => setWeather('snowy')}>雪</button>
    </div>
  );
}

リストのフィルタリング

import { useState } from 'react';

function TodoList() {
  const [todos, setTodos] = useState([
    { id: 1, text: '買い物に行く', completed: false },
    { id: 2, text: '宿題をする', completed: true },
    { id: 3, text: '掃除をする', completed: false }
  ]);

  const [filter, setFilter] = useState('all');

  const filteredTodos = todos.filter(todo => {
    if (filter === 'completed') return todo.completed;
    if (filter === 'incomplete') return !todo.completed;
    return true; // 'all'の場合は全て表示
  });

  return (
    <div>
      <h3>TODOリスト</h3>
      <div>
        <button onClick={() => setFilter('all')}>全て</button>
        <button onClick={() => setFilter('completed')}>完了済み</button>
        <button onClick={() => setFilter('incomplete')}>未完了</button>
      </div>
      <ul>
        {filteredTodos.map(todo => (
          <li key={todo.id} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
}

配列と条件分岐を組み合わせることで、動的で柔軟な画面表示を実現できます。

Reactアプリの構造とベストプラクティス

プロジェクトのフォルダ構成

Reactアプリが大きくなってきたら、ファイルを整理することが大切です。

推奨されるフォルダ構成

src/
├── components/          # 再利用可能なコンポーネント
│   ├── Button.js       # ボタンコンポーネント
│   ├── Header.js       # ヘッダーコンポーネント
│   └── UserCard.js     # ユーザーカードコンポーネント
├── pages/              # ページ単位のコンポーネント
│   ├── Home.js         # ホームページ
│   ├── About.js        # アバウトページ
│   └── Contact.js      # お問い合わせページ
├── hooks/              # カスタムフック
├── utils/              # 便利な関数
├── styles/             # CSSファイル
├── App.js              # メインのアプリコンポーネント
└── index.js            # エントリーポイント

コンポーネントを分割するメリット

悪い例:全てを一つのコンポーネントに書く

function App() {
  return (
    <div>
      {/* ヘッダー部分 */}
      <header style={{ backgroundColor: '#333', color: 'white', padding: '1rem' }}>
        <h1>マイサイト</h1>
        <nav>
          <a href="/">ホーム</a>
          <a href="/about">アバウト</a>
        </nav>
      </header>

      {/* メイン部分 */}
      <main style={{ padding: '2rem' }}>
        <h2>ようこそ</h2>
        <p>このサイトについて説明します...</p>
        {/* 長い内容が続く... */}
      </main>

      {/* フッター部分 */}
      <footer style={{ backgroundColor: '#666', color: 'white', padding: '1rem' }}>
        <p>&copy; 2024 マイサイト</p>
      </footer>
    </div>
  );
}

良い例:コンポーネントに分割する

// Header.js
function Header() {
  return (
    <header style={{ backgroundColor: '#333', color: 'white', padding: '1rem' }}>
      <h1>マイサイト</h1>
      <nav>
        <a href="/">ホーム</a>
        <a href="/about">アバウト</a>
      </nav>
    </header>
  );
}

// Main.js
function Main() {
  return (
    <main style={{ padding: '2rem' }}>
      <h2>ようこそ</h2>
      <p>このサイトについて説明します...</p>
    </main>
  );
}

// Footer.js
function Footer() {
  return (
    <footer style={{ backgroundColor: '#666', color: 'white', padding: '1rem' }}>
      <p>&copy; 2024 マイサイト</p>
    </footer>
  );
}

// App.js
function App() {
  return (
    <div>
      <Header />
      <Main />
      <Footer />
    </div>
  );
}

開発で気をつけるポイント

コンポーネント設計のコツ

  • 小さく分割する:一つのコンポーネントは50行以内を目安に
  • 役割を明確にする:何をするコンポーネントなのかが分かるように
  • 再利用を考える:似たような部分は共通のコンポーネントにする

命名規則

  • コンポーネント名:大文字から始める(PascalCase)
  • ファイル名:コンポーネント名と同じにする
  • 変数名:小文字から始める(camelCase)

state管理のポイント

  • 必要最小限:本当に状態管理が必要なものだけstateにする
  • 適切な場所:どのコンポーネントでstateを管理するか考える
  • 不変性を保つ:stateを直接変更せず、常に新しい値を作る

良い例:stateの管理

// ✅ 正しい:新しい配列を作成
const addItem = (newItem) => {
  setItems([...items, newItem]);
};

// ❌ 間違い:既存の配列を直接変更
const addItem = (newItem) => {
  items.push(newItem);
  setItems(items);
};

パフォーマンスを向上させるコツ

React.memoを使った最適化

import React from 'react';

// このコンポーネントはpropsが変わらない限り再レンダリングされない
const UserCard = React.memo(function UserCard({ name, age }) {
  return (
    <div>
      <h3>{name}</h3>
      <p>年齢:{age}歳</p>
    </div>
  );
});

useCallbackを使った関数の最適化

import { useState, useCallback } from 'react';

function TodoApp() {
  const [todos, setTodos] = useState([]);

  // この関数はtodosが変わった時だけ再作成される
  const addTodo = useCallback((text) => {
    setTodos(prev => [...prev, { id: Date.now(), text }]);
  }, []);

  return (
    <div>
      <TodoForm onAddTodo={addTodo} />
      <TodoList todos={todos} />
    </div>
  );
}

適切な構造設計により、コードの保守性と可読性が大幅に向上します。

まとめ

Reactは「コンポーネント・props・state」という3つの基本概念を中心に動くライブラリです。

学習のロードマップ

  1. 基本概念の理解:コンポーネント、props、stateの仕組み
  2. 実践練習:簡単なアプリを作ってみる
  3. 応用技術:フック、ライフサイクル、状態管理の学習
  4. 実際の開発:本格的なプロジェクトに参加

コメント

タイトルとURLをコピーしました