1. ホーム
  2. 記事一覧
  3. Reactの基本、コンポーネントを理解する

2024.06.30

Reactの基本、コンポーネントを理解する

はじめに

Reactは、ユーザーインターフェースを構成するためのJavaScriptライブラリです。昨今では、ウェブアプリケーションやモバイルアプリケーションのインターフェースを作成するために、多くの開発現場で使用されています。開発者が高性能で保守性の高いアプリケーションを作成できるように設計されています。Reactを学ぶことで、モダンなウェブ開発のスキルを身につけることができるため、フロントエンドエンジニアを目指す上で、必須のスキルと言っても過言ではありません。

フロントエンドエンジニアになりたい、初めてReactを学ぶ方に向けて、この記事ではReactの基本であるコンポーネントについて解説していきます。コンポーネントを学ぶことで、これからのReact学習の理解度が深まります。基本を学び、フロントエンドエンジニアへの道を進んでいきましょう!

Reactの基本については以下のページで詳しく解説しています。Reactについて、環境構築方法などを知りたい方はご覧ください。

https://envader.plus/article/341

Reactの環境構築にはViteがおすすめです。Viteは高速に開発環境を立ち上げることができる環境構築ツールです。以下の記事ではViteを使用したVue.jsの環境構築について解説していますが、同じ方法でReactの環境構築も可能です。

https://envader.plus/course/9/scenario/1091

コンポーネントとJSXについて

コンポーネント

Reactにおけるコンポーネントとは、UIを構成するための再利用可能な要素(部品)です。Reactアプリケーションは、複数のコンポーネントを組み合わせてUIを構成します。

UIのパーツや機能をそれぞれのコンポーネントに分割することで、1つ1つの部品として使用でき、異なる場所で何度でも使用できます。何度も使用できる=再利用可能ということです。これにより、コードの重複を避けたり記述量を減らせたりするため、作業の効率化が図れ、メンテナンスも容易になります。

以下のようなカードコンポーネントは、複数のコンポーネントに分割して構成することができます。コンポーネントに分割することで、別のUI構成での再利用が容易になります。

ButtonコンポーネントをFormコンポーネントで再利用した例です。このように同じコンポーネントを異なるUI構成でも使用することができるため、コードの記述量を削減し、メンテナンスを容易にします。

コンポーネントは以下の例のように記述します。公式サイトでは「React コンポーネントとは、マークアップを添えることができるJavaScript関数」と説明されていますが、これはJSX(マークアップ)を戻り値として返すJavaScript関数ということです。以下のGreeting関数は、文字列「Hello, World!」を含むh1要素を返します。

function Greeting() {
    return <h1>Hello, World!</h1>;
}

JSX

次にJSXについて学びましょう。JSX(JavaScript XML)は、JavaScriptの構文を拡張したもので、JavaScriptの中でHTMLのような記述をすることが可能になります。これにより、画面に表示するコンポーネントをわかりやすく書くことができるため、多くの開発現場で使用されています。見た目はHTMLに似ていますが、実際にはJavaScriptで構成されており、ブラウザが理解できるようにコンパイル(変換)されます。

export default function App() {
  return (
    <>
      <h1>Hello, World!</h1>
      <h2>React × エンベーダー</h2>
      <button>Button</button>
    </>
  );
}

コンポーネントの作成

では実際にコンポーネントを作成してみましょう。Reactには関数コンポーネントとクラスコンポーネントの2通りの記述方法がありますが、この記事では現在主流となっている関数コンポーネントをベースに解説します。

ハンズオンでコードの記述を試したい方には、以下のサイトがおすすめです。Reactの環境構築が不要で、ブラウザ上でコードの記述を手軽に試すことができます。

App.jsに文字列とボタンのコンポーネントを3つ作成した例です。

// ファイル名:App.js

export default function App() {
  return (
    <>
      <h1>Hello, World!</h1>
      <h2>React × エンベーダー</h2>
      <button>Button</button>
    </>
  );
}

この記述内容の出力結果は以下のようになります。

コードの内容を1つずつ確認していきます。export default functionは、ファイルから特定の関数を他のファイルで使えるようにエクスポートするための方法です。この方法を使うと、エクスポートされた関数がそのファイルのメインの機能として扱われ、他のファイルにインポートして使用することができます。

export default function App() {
  return ...
}

次にreturnの内部を確認しましょう。return内には3つのコンポーネント<h1>,<h2>,<button>があり、その1つ上の階層にはフラグメント<></>が付けられています。Reactコンポーネントは複数の要素を返すことができないため、<div>タグやフラグメント<>で複数のコンポーネントを1つのグループにする必要があります。フラグメント<>を使用すると、不必要なHTML要素を追加せずに複数の要素をグループ化することが可能です。コードの記述がシンプルになり、コードを読みやすくします。

// ファイル名:App.js

export default function App() {
  return (
    <>
      <h1>Hello, World!</h1>
      <h2>React × エンベーダー</h2>
      <button>Button</button>
    </>
  );
}

以下の記述例は複数のコンポーネントがグループ化されていないためエラーとなります。

// ファイル名:App.js
// return内のコンポーネントがグループ化されてないためエラーとなります

export default function App() {
  return (
      <h1>Hello, World!</h1>
      <h2>React × エンベーダー</h2>
      <button>Button</button>
  );
}

通常関数とアロー関数について

コンポーネントには、通常関数とアロー関数の2通りの記述方法があります。以下の例は2つとも 文字列「Hello, World!」を含むh1要素を返しますが、関数の内部構造は厳密には異なります。どちらを使用するかは、プロジェクトやチームのルールによって使い分けると良いでしょう。

通常関数で記述した例です。

function Greeting() {
    return <h1>Hello, World!</h1>;
}

アロー関数で記述した例です。

const Greeting = () => {
		return <h1>Hello, World!</h1>;
};

コンポーネントの分割

コンポーネントをさらに再利用しやすくするには、部品を別ファイルに分けて作成するのが一般的です。ファイルを分けることにより、そのファイルが何の部品や機能かが一目で分かりやすく、さまざまな場所での再利用が容易になります。コンポーネントのファイルは、それぞれのファイルにインポートやエクスポートをすることで使用できます。

分割前のApp.jsの状態です。これからreturn内部にある3つのコンポーネントを分割します。

// ファイル名:App.js

export default function App() {
  return (
    <>
      <h1>Hello, World!</h1>        {/* Greetingコンポーネントに分割 */}
      <h2>React × エンベーダー</h2>   {/* Collaborateコンポーネントに分割 */}
      <button>Button</button>       {/* Buttonコンポーネントに分割 */}
    </>
  );
}

新規に以下の名前をつけたファイルを3つ作成します。

  • Greeting.js
  • Collaborate.js
  • Button.js

それぞれのファイルに次の内容を記述します。export default function <関数名>を付けることで関数をエクスポートし、他のコンポーネントでその関数を使用することができます。関数名はパスカルケース(大文字始まり)で記述する必要があり、これによりReactがコンポーネントと認識します。

Greeting.js

export default function Greeting() {
  return <h1>Hello, World!</h1>;
}

Collaborate.js

export default function Collaborate() {
  return <h2>React × エンベーダー</h2>;
}

Button.js

export default function Button() {
  return <button>Button</button>;
}

3つに分割したコンポーネントをApp.jsにインポートします。以下の1-3行目のようなインポート文を記述することで、App.js内で該当のコンポーネントを使用することができます。

次に、export default function App内に、インポートしたコンポーネントを記述します。コンポーネント名も大文字始まりで記述し、閉じタグを入れる必要があります。コンポーネントに子要素がない場合は<Button />のように閉じタグを記述することができます。

App.js

import Greeting from './Greeting';
import Collaborate from './Collaborate';
import Button from './Button';

export default function App() {
  return (
    <>
      <Greeting />
      <Collaborate />
      <Button />
    </>
  );
}

このコードの出力結果です。コンポーネントを分割する前と同じ内容で出力できました。

コンポーネントファイルの拡張子の違い

Reactでのコンポーネントファイルの拡張子は、.jsx.js が使用されています。

拡張子.jsxは、ファイルにJSXが含まれていることを明示します。拡張子に.jsxを使うことで、そのファイルがJSXを含んでいることが一目で分かるため、開発者やコードレビュアーにとってファイルの内容を予測しやすくなります。

拡張子.jsは、通常のJavaScriptコードで作成したファイルに使用されます。ファイル内にJSXを含む場合でも.jsを使うことは可能ですが、その場合はファイルの内容を確認しないとJSXを含んでいるかどうかが分かりにくくなります。

プロジェクトによっては、JSXを含むファイルには拡張子.jsxを使うといったルールを設けている場合がありますので、そのルールによって拡張子を使い分けると良いでしょう。

コンポーネントのエクスポートとインポートの種類

コンポーネントのエクスポート

Reactコンポーネントのエクスポートは、デフォルトエクスポートと名前付きエクスポートの2種類の方法があります。

  • デフォルトエクスポート

    1つのファイル内に1つのみ、デフォルトエクスポートするコンポーネントを置くことが可能です。1つのファイルから、1つのコンポーネントをエクスポートする際に使用されます。

  • 名前付きエクスポート

    1つのファイル内に複数のコンポーネントを置くことができます。1つのファイルから、複数のコンポーネントをエクスポートする際に有用です。

デフォルトエクスポートと名前付きエクスポートを、1つのファイル内に一緒に記述することも可能です。

以上の説明をまとめると、以下の図の通りとなります。

コンポーネントのインポート

エクスポートの方法によってインポートする記述内容は異なり、それぞれ以下の通りとなります。インポートするファイル名の拡張子は省略できます。

構文エクスポート文インポート文
デフォルトexport default function 関数名( ) { }import 関数名 from './ファイル名' ;
名前付きexport function 関数名( ) { }import { 関数名 } from './ファイル名' ;
  • デフォルト構文

    インポート文の関数名は任意の名前でもコンポーネントをインポートすることができます。例えば、Buttonという関数名でエクスポートしたコンポーネントを、import ClickButton fromにしてもインポートすることが可能です。

  • 名前付き構文

    インポート文の関数名は{ }で囲い、エクスポート側とインポート側の関数名を一致させます。1つのファイルから複数のコンポーネントをインポートしたい場合は、すべての関数名を入力する必要があります。例えば、import { YesButton, NoButton } from のように記述します。

デフォルトエクスポートと名前付きエクスポートの例

Button.jsから2種のボタンを、1つのデフォルトエクスポートと1つの名前付きエクスポートで行います。

// ファイル名:Button.js

// デフォルトエクスポート
export default function YesButton() {
    return <button>Yes</button>;
}

// 名前付きエクスポート
export function NoButton() {
    return <button>No</button>;
}

App.jsで以下のように記述し、2種のボタンをそれぞれインポートします。

// ファイル名:App.js

// デフォルトエクスポートのインポート文
import YesButton from './Button';

// 名前付きエクスポートのインポート文
import { NoButton } from './Button';

export default function App() {
    return (
        <>
            <YesButton />
            <NoButton />
        </>
    );
}

デフォルトエクスポートと名前付きエクスポートを1つのインポート文にまとめることもできます。

// デフォルトエクスポートと名前付きエクスポートのインポート文
import YesButton, { NoButton } from './Button';

出力結果は以下のようになり、2種のボタンコンポーネントのエクスポートとインポートができました。

どちらの記述方法を使用するかは、プロジェクトやチームによって異なります。こちらも、プロジェクトやチームのルールによって使い分けると良いでしょう。

コンポーネントがブラウザに表示されるまでのプロセス

ここまでReactコンポーネントについて学んできました。最後にReactアプリケーションで作成したコンポーネントがどのようにレンダリングされ、ブラウザの画面に表示されているかを説明します。

Reactアプリケーションの最初のエントリーポイント(アプリケーションの実行が開始される場所)はpublicフォルダ内にあるindex.htmlです。このファイルは静的なHTMLファイルで、Reactコンポーネントがレンダリングされるためのベースとなります。HTMLファイルには、<div id="root"></div>という要素があり、Reactアプリケーションはこのdiv要素の中にレンダリングされます。

// ファイル名:index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>React App</title>
    </head>
    <body>
        <div id="root"></div> <!-- この中にReactアプリケーションがレンダリングされる -->
    </body>
</html>

次に、srcフォルダ内にあるindex.jsファイルを見てみましょう。index.jsファイルは、ReactアプリケーションのJavaScriptエントリーポイントです。index.jsでは、Reactコンポーネントをブラウザにレンダリングするために必要なライブラリをインポートし、App.jsファイルからAppコンポーネントをインポートします。そして、root.renderメソッドを使用して、Appコンポーネントをindex.htmlの<div id="root">要素にレンダリングします。

// ファイル名:index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <App />  <!-- root.renderを使用してindex.htmlの<div id="root">の中にレンダリングされる -->
    </React.StrictMode>
);

最後にApp.jsについてです。App.jsファイルは、Reactアプリケーションのメインコンポーネントを定義します。ここで、アプリケーション全体の構造や主要なコンポーネントが指定されます。App.jsに記述されたコンポーネントはindex.jsファイルを通じてブラウザにレンダリングされます。

// ファイル名:App.js

import Greeting from './Greeting';
import Collaborate from './Collaborate';
import Button from './Button';

export default function App() {
  return (
    <>
      <Greeting />
      <Collaborate />
      <Button />
    </>
  );
}

この記事で学んだこと

  • コンポーネントについて

    Reactにおけるコンポーネントとは、UIを構成する際の再利用可能な要素(部品)です。Reactアプリケーションは、複数のコンポーネントを組み合わせてUIを構成します。コンポーネントは、JSXを戻り値として返すJavaScript関数です。

  • コンポーネントのエクスポートとインポート

    コンポーネントのエクスポートとインポートには、デフォルトエクスポートと名前付きエクスポートの2種類があります。デフォルトエクスポートは1つのみコンポーネントをエクスポートし、名前付きエクスポートは複数のコンポーネントをエクスポートする際に使用されます。

  • コンポーネントがブラウザに表示されるプロセス

    作成したコンポーネントは、Reactアプリケーションのメインコンポーネントを定義したApp.jsファイルから、index.jsを経てエントリーポイントであるindex.htmlにレンダリングされ、ブラウザに表示されます。

参考資料

以下のリンクは、この記事で説明した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご参照ください。

【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

IT未経験者必見 USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事