Reactでカスタムコンポーネントを作成する方法

提供:Dev Guides
移動先:案内検索

著者は、 Creative Commons を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

このチュートリアルでは、Reactでカスタムコンポーネントを作成する方法を学習します。 コンポーネントは、アプリケーションで再利用できる独立した機能であり、すべてのReactアプリケーションの構成要素です。 多くの場合、これらは単純な JavaScript関数およびクラスですが、カスタマイズされたHTML要素であるかのように使用します。 ボタン、メニュー、およびその他のフロントエンドページのコンテンツはすべてコンポーネントとして作成できます。 コンポーネントには、状態情報と表示マークダウンを含めることもできます。

Reactでコンポーネントを作成する方法を学んだ後は、複雑なアプリケーションを、構築と保守が容易な小さな部分に分割できるようになります。

このチュートリアルでは、クリックすると名前が表示される絵文字のリストを作成します。 絵文字はカスタムコンポーネントを使用して作成され、別のカスタムコンポーネント内から呼び出されます。 このチュートリアルの終わりまでに、JavaScriptクラスとJavaScript関数の両方を使用してカスタムコンポーネントを作成し、既存のコードを再利用可能な部分に分離する方法と、コンポーネントを読み取り可能なファイル構造に格納する方法を理解します。

前提条件

  • Node.jsを実行する開発環境が必要になります。 このチュートリアルは、Node.jsバージョン10.20.1およびnpmバージョン6.14.4でテストされました。 これをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはのPPAを使用したインストール]セクションの手順に従います。 Ubuntu18.04にNode.jsをインストールする方法。
  • Create ReactAppでアプリを作成できる必要があります。 Create React Appを使用してアプリケーションをインストールする手順については、 Create ReactAppを使用してReactプロジェクトをセットアップする方法を参照してください。
  • JSX構文を使用します。これについては、JSXチュートリアルで要素を作成する方法で学ぶことができます。
  • また、 JavaScriptでコーディングする方法にあるJavaScriptの基本的な知識と、HTMLおよびCSSの基本的な知識も必要です。 HTMLとCSSの優れたリソースは、 Mozilla DeveloperNetworkです。

ステップ1—Reactプロジェクトのセットアップ

このステップでは、CreateReactAppを使用してプロジェクトのベースを作成します。 また、デフォルトのプロジェクトを変更して、絵文字のリストにマッピングし、少量のスタイルを追加して、ベースプロジェクトを作成します。

まず、新しいプロジェクトを作成します。 ターミナルを開き、次のコマンドを実行します。

npx create-react-app tutorial-03-component

これが完了したら、プロジェクトディレクトリに移動します。

cd tutorial-03-component

App.jsコードをテキストエディタで開きます。

nano src/App.js

次に、Create React Appで作成されたテンプレートコードを取り出し、その内容を絵文字のリストを表示する新しいReactコードに置き換えます。

チュートリアル-03-component/src / App.js

import React from 'react';
import './App.css';

const displayEmojiName = event => alert(event.target.id);
const emojis = [
  {
    emoji: '😀',
    name: "test grinning face"
  },
  {
    emoji: '🎉',
    name: "party popper"
  },
  {
    emoji: '💃',
    name: "woman dancing"
  }
];

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

このコードは、JSX構文を使用して、emojis array上でmap()を実行し、それらを<li>リストアイテムとしてリストします。 また、onClick events を添付して、ブラウザに絵文字データを表示します。 コードの詳細については、JSXの詳細な説明が含まれているJSXを使用してReact要素を作成する方法を確認してください。

ファイルを保存して閉じます。 logo.svgファイルはテンプレートの一部であり、参照していないため、これで削除できます。

rm src/logo.svg

次に、スタイルを更新します。 src/App.cssを開きます:

nano src/App.css

コンテンツを次のCSSに置き換えて、要素を中央に配置し、フォントを調整します。

チュートリアル-03-component/src / App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

これは、flexを使用して、メインの<h1>とリスト要素を中央に配置します。 また、デフォルトのボタンスタイルと<li>スタイルが削除され、絵文字が一列に並ぶようになります。 詳細については、JSXを使用してReact要素を作成する方法を参照してください。

ファイルを保存して終了します。

プロジェクトのルートで別のターミナルウィンドウを開きます。 次のコマンドでプロジェクトを開始します。

npm start

コマンドを実行すると、 http:// localhost:3000のWebブラウザーでプロジェクトが実行されていることがわかります。

プロジェクトで作業している間は、これを実行したままにします。 プロジェクトを保存するたびに、ブラウザは自動更新され、最新のコードが表示されます。

Hello、World と、App.jsファイルにリストした3つの絵文字を含むプロジェクトページが表示されます。

コードを設定したので、Reactでコンポーネントをまとめることができます。

ステップ2—Reactクラスを使用して独立したコンポーネントを作成する

プロジェクトを実行したので、カスタムコンポーネントの作成を開始できます。 このステップでは、ベースのReact Component class を拡張して、独立したReactコンポーネントを作成します。 新しいクラスを作成し、メソッドを追加し、render関数を使用してデータを表示します。

Reactコンポーネントは、ページ全体で再利用できる自己完結型の要素です。 小さく焦点を絞ったコードを作成することで、アプリケーションの成長に合わせてコードを移動して再利用できます。 ここで重要なのは、それらが自己完結型で集中しているため、コードを論理的な部分に分離できることです。 実際、すでに論理的に分離されたコンポーネントを使用しています。App.jsファイルは機能コンポーネントであり、ステップ3で詳しく説明します。

カスタムコンポーネントには、クラスベース機能の2種類があります。 作成する最初のコンポーネントは、クラスベースのコンポーネントです。 絵文字ビューアの手順を説明するInstructionsという新しいコンポーネントを作成します。

注:クラスベースのコンポーネントは、Reactコンポーネントを作成するための最も一般的な方法でした。 しかし、 React Hooks の導入により、多くの開発者やライブラリは機能コンポーネントの使用に移行しています。

現在では機能コンポーネントが標準になっていますが、レガシーコードにはクラスコンポーネントが含まれていることがよくあります。 それらを使用する必要はありませんが、それらを認識する方法を知る必要があります。 また、状態管理など、多くの将来の概念を明確に紹介します。 このチュートリアルでは、クラスコンポーネントと機能コンポーネントの両方を作成する方法を学習します。


まず、新しいファイルを作成します。 慣例により、コンポーネントファイルは大文字になります。

touch src/Instructions.js

次に、テキストエディタでファイルを開きます。

nano src/Instructions.js

まず、ReactComponentクラスをインポートし、次の行でInstructionsをエクスポートします。

チュートリアル-03-component/src / Instructions.js

import React, { Component } from 'react';

export default class Instructions extends Component {}

Reactをインポートすると、JSXが変換されます。 Componentは、コンポーネントを作成するために拡張する基本クラスです。 これを拡張するには、コンポーネントの名前(Instructions)を持つクラスを作成し、ベースComponentexport行で拡張しました。 また、クラス宣言の先頭にexport defaultキーワードを指定して、このクラスをデフォルトとしてエクスポートしています。

クラス名は大文字で、ファイルの名前と一致する必要があります。 これは、コンポーネントの名前を表示するデバッグツールを使用する場合に重要です。 名前がファイル構造と一致する場合は、関連するコンポーネントを見つけやすくなります。

基本のComponentクラスには、カスタムクラスで使用できるいくつかのメソッドがあります。 最も重要な方法であり、このチュートリアルで使用する唯一の方法は、render()方法です。 render()メソッドは、ブラウザに表示するJSXコードを返します。

まず、<p>タグにアプリの簡単な説明を追加します。

チュートリアル-03-component/src / Instructions.js

import React, { Component } from 'react';

export class Instructions extends Component {

  render() {
    return(
      <p>Click on an emoji to view the emoji short name.</p>
    )
  }

}

ファイルを保存して閉じます。 この時点では、ブラウザに変更はありません。 これは、新しいコンポーネントをまだ使用していないためです。 コンポーネントを使用するには、ルートコンポーネントに接続する別のコンポーネントにコンポーネントを追加する必要があります。 このプロジェクトでは、<App>index.jsのルートコンポーネントです。 アプリケーションに表示するには、<App>コンポーネントに追加する必要があります。

テキストエディタでsrc/App.jsを開きます。

nano src/App.js

まず、コンポーネントをインポートする必要があります。

チュートリアル-03-component/src / App.js

import React from 'react';

import Instructions from './Instructions';

import './App.css';

...

export default App;

これはデフォルトのインポートであるため、任意の名前にインポートできます。 読みやすくするために名前の一貫性を保つのが最善です。インポートはコンポーネント名と一致し、ファイル名と一致する必要がありますが、唯一の確固たるルールは、コンポーネントが大文字で始まる必要があるということです。 これが、ReactがReactコンポーネントであることを認識する方法です。

コンポーネントをインポートしたので、カスタムHTML要素であるかのようにコードの残りの部分に追加します。

チュートリアル-03-component/src / App.js

import React from 'react';

import Instructions from './Instructions.js'

...
function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

このコードでは、コンポーネントを山かっこでラップしました。 このコンポーネントには子がないため、/>で終了することで自己終了することができます。

ファイルを保存します。 これを行うと、ページが更新され、新しいコンポーネントが表示されます。

テキストができたので、画像を追加できます。 wikimedia から絵文字画像をダウンロードし、次のコマンドを使用してsrcディレクトリにemoji.svgとして保存します。

curl -o src/emoji.svg https://upload.wikimedia.org/wikipedia/commons/3/33/Twemoji_1f602.svg

curl はURLにリクエストを送信し、-oフラグを使用するとファイルをsrc/emoji.svgとして保存できます。

次に、コンポーネントファイルを開きます。

nano src/Instructions.js

絵文字をインポートし、動的リンクを使用してカスタムコンポーネントに追加します。

チュートリアル-03-component/src / Instructions.js

import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <>
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </>
    )
  }
}

インポート時にファイル拡張子.svgを含める必要があることに注意してください。 インポートすると、コードのコンパイル時にwebpackによって作成される動的パスがインポートされます。 詳細については、CreateReactアプリを使用してReactプロジェクトを設定する方法を参照してください。

また、<img>および<p>タグを空のタグでラップして、単一の要素を返すようにする必要があります。

ファイルを保存します。 リロードすると、画像は他のコンテンツと比較して非常に大きくなります。

画像を小さくするには、CSSとclassNameをカスタムコンポーネントに追加する必要があります。

まず、Instructions.jsで、空のタグをdivに変更し、instructionsclassNameを指定します。

チュートリアル-03-component/src / Instructions.js

import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

ファイルを保存して閉じます。 次にApp.cssを開きます。

nano src/App.css

.instructionsクラスセレクターのルールを作成します。

チュートリアル-03-component/src / App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

flexスタイリングのdisplayを追加すると、imgpflexboxの中央に配置されます。 すべてがflex-direction: column;と垂直に並ぶように方向を変更しました。 align-items: center;の線は、要素を画面の中央に配置します。

要素が揃ったので、画像サイズを変更する必要があります。 100pxdiv内のimgwidthheightを与えます。

チュートリアル-03-component/src / App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

ファイルを保存して閉じます。 ブラウザがリロードされ、画像がはるかに小さいことがわかります。

この時点で、独立した再利用可能なカスタムコンポーネントを作成しました。 再利用可能かどうかを確認するには、App.jsに2番目のインスタンスを追加します。

App.jsを開きます:

nano src/App.js

App.jsで、コンポーネントの2番目のインスタンスを追加します。

チュートリアル-03-component/src / App.js

import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

ファイルを保存します。 ブラウザがリロードされると、コンポーネントが2回表示されます。

この場合、Instructionsの2つのインスタンスは必要ありませんが、コンポーネントを効率的に再利用できることがわかります。 カスタムボタンまたはテーブルを作成する場合、1ページで複数回使用する可能性が高いため、カスタムコンポーネントに最適です。

今のところ、余分な画像タグを削除できます。 テキストエディタで、2番目の<Instructions />を削除し、ファイルを保存します。

チュートリアル-03-component/src / App.js

import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

これで、親コンポーネントに複数回追加できる、再利用可能な独立したコンポーネントができました。 現在の構造は少数のコンポーネントで機能しますが、わずかな問題があります。 すべてのファイルが混在しています。 <Instructions>のイメージは、<App>のアセットと同じディレクトリにあります。 また、<App>のCSSコードと<Instructions>のCSSを混在させています。

次のステップでは、機能、スタイル、および依存関係をグループ化することで各コンポーネントに独立性を与えるファイル構造を作成し、必要に応じてそれらを移動できるようにします。

ステップ3—読み取り可能なファイル構造を作成する

このステップでは、画像、CSS、その他のJavaScriptファイルなどのコンポーネントとそのアセットを整理するためのファイル構造を作成します。 アセットタイプではなく、コンポーネントごとにコードをグループ化します。 つまり、CSS、画像、JavaScript用の個別のディレクトリはありません。 代わりに、関連するCSS、JavaScript、および画像を含むコンポーネントごとに個別のディレクトリがあります。 どちらの場合も、あなたは懸念を分離しています

独立したコンポーネントがあるため、関連するコードをグループ化するファイル構造が必要です。 現在、すべてが同じディレクトリにあります。 srcディレクトリのアイテムを一覧表示します。

ls src/

出力は、物事がかなり雑然としていることを示します。

OutputApp.css                 Instructions.js         index.js
App.js                  emoji.svg               serviceWorker.js
App.test.js             index.css               setupTests.js

ルートコンポーネント(index.cssおよびindex.js)およびカスタムコンポーネントInstructions.js

Reactはファイル構造について意図的に不可知論者です。 特定の構造を推奨するものではなく、プロジェクトはさまざまな異なるファイル階層で機能します。 ただし、ナビゲートが困難なコンポーネント、CSSファイル、および画像でルートディレクトリが過負荷にならないように、いくつかの順序を追加することをお勧めします。 また、明示的な名前を付けると、プロジェクトのどの部分が関連しているかを簡単に確認できます。 たとえば、Logo.svgという名前の画像ファイルは、Header.jsというコンポーネントの一部ではない場合があります。

最も単純な構造の1つは、コンポーネントごとに個別のディレクトリを持つcomponentsディレクトリを作成することです。 これにより、アセットをコンポーネントとグループ化しながら、serviceWorkerなどの構成コードとは別にコンポーネントをグループ化できます。

Componentsディレクトリの作成

まず、componentsというディレクトリを作成します。

mkdir src/components

次に、次のコンポーネントとコードをディレクトリに移動します:App.cssApp.jsApp.test.jsInstructions.js、およびemoji.svg

mv src/App.* src/components/
mv src/Instructions.js src/components/
mv src/emoji.svg src/components/

ここでは、ワイルドカード(*)を使用して、App.で始まるすべてのファイルを選択しています。

コードを移動すると、npm startを実行している端末でエラーが表示されます。

OutputFailed to compile.

./src/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'

すべてのコードが相対パスを使用してインポートされていることを忘れないでください。 一部のファイルのパスを変更する場合は、コードを更新する必要があります。

これを行うには、index.jsを開きます。

nano src/index.js

次に、Appインポートのパスを変更して、components/ディレクトリからインポートします。

チュートリアル-03-component/src / index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

ファイルを保存して閉じます。 スクリプトが変更を検出し、エラーが消えます。

これで、別のディレクトリにコンポーネントができました。 アプリケーションがより複雑になると、APIサービス、データストア、およびユーティリティ関数用のディレクトリが作成される場合があります。 コンポーネントコードを分離することが最初のステップですが、InstructionsのCSSコードがApp.cssファイルに混在しています。 この論理的な分離を作成するには、最初にコンポーネントを別々のディレクトリに移動します。

コンポーネントを個々のディレクトリに移動する

まず、<App>コンポーネント専用のディレクトリを作成します。

mkdir src/components/App

次に、関連ファイルを新しいディレクトリに移動します。

mv src/components/App.* src/components/App

これを行うと、前のセクションと同様のエラーが発生します。

OutputFailed to compile.

./src/components/App.js
Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'

この場合、2つのことを更新する必要があります。 まず、index.jsのパスを更新する必要があります。

index.jsファイルを開きます。

nano src/index.js

次に、Appのインポートパスを更新して、AppディレクトリのAppコンポーネントを指すようにします。

チュートリアル-03-component/src / index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

ファイルを保存して閉じます。 アプリケーションはまだ実行されません。 次のようなエラーが表示されます。

OutputFailed to compile.

./src/components/App/App.js

Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'

<Instructions><App>コンポーネントと同じディレクトリレベルではないため、インポートパスを変更する必要があります。 その前に、Instructionsのディレクトリを作成します。 src/componentsディレクトリにInstructionsというディレクトリを作成します。

mkdir src/components/Instructions

次に、Instructions.jsemoji.svgをそのディレクトリに移動します。

mv src/components/Instructions.js src/components/Instructions
mv src/components/emoji.svg src/components/Instructions

Instructionsコンポーネントディレクトリが作成されたので、ファイルパスの更新を完了して、コンポーネントをアプリに接続できます。

importパスの更新

コンポーネントが個々のディレクトリにあるので、App.jsでインポートパスを調整できます。

App.jsを開きます:

nano src/components/App/App.js

パスは相対パスであるため、src/componentsという1つのディレクトリを上に移動してから、Instructions.jsInstructionsディレクトリに移動する必要がありますが、これはJavaScriptファイルであるため、最終的なインポートは必要ありません。

チュートリアル-03-component/src / components / App / App.js

import React from 'react';

import Instructions from '../Instructions/Instructions.js';

import './App.css';

...

export default App;

ファイルを保存して閉じます。 インポートがすべて正しいパスを使用しているので、ブラウザが更新され、アプリケーションが表示されます。

注:各ディレクトリのルートファイルを呼び出すこともできますindex.js。 たとえば、src/components/App/App.jsの代わりに、src/components/App/index.jsを作成できます。 これの利点は、インポートがわずかに少ないことです。 パスがディレクトリを指している場合、インポートはindex.jsファイルを探します。 src/index.jsファイルのsrc/components/App/index.jsのインポートは、import ./components/Appになります。 このアプローチの欠点は、同じ名前のファイルがたくさんあることです。これにより、一部のテキストエディタで読みにくくなる可能性があります。 最終的には、個人およびチームの決定ですが、一貫性を保つことが最善です。


共有ファイルのコードを分離する

現在、各コンポーネントには独自のディレクトリがありますが、すべてが完全に独立しているわけではありません。 最後のステップは、InstructionsのCSSを別のファイルに抽出することです。

まず、src/components/InstructionsでCSSファイルを作成します。

touch src/components/Instructions/Instructions.css

次に、テキストエディタでCSSファイルを開きます。

nano src/components/Instructions/Instructions.css

前のセクションで作成したCSSの説明を追加します。

チュートリアル-03-component/src / components / Instructions / Instructions.css

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

ファイルを保存して閉じます。 次に、CSSの説明をsrc/components/App/App.cssから削除します。

nano src/components/App/App.css

.instructionsに関する行を削除します。 最終的なファイルは次のようになります。

チュートリアル-03-component/src / components / App / App.css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

ファイルを保存して閉じます。 最後に、CSSをInstructions.jsにインポートします。

nano src/components/Instructions/Instructions.js

相対パスを使用してCSSをインポートします。

チュートリアル-03-component/src / components / Instructions / Instructions.js

import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

ファイルを保存して閉じます。 ブラウザウィンドウは以前と同じように表示されますが、すべてのファイルアセットが同じディレクトリにグループ化されている点が異なります。

次に、構造を最後に見てみましょう。 まず、src/ディレクトリ:

ls src

components/ディレクトリとserviceWorker.jssetupTests.jsなどのユーティリティファイルの横に、ルートコンポーネントindex.jsと関連するCSSindex.cssがあります。

Outputcomponents              serviceWorker.js
index.css               setupTests.js
index.js

次に、componentsの内部を見てください。

ls src/components

各コンポーネントのディレクトリが表示されます。

OutputApp             Instructions

各コンポーネントの内部を見ると、コンポーネントコード、CSS、テスト、およびイメージファイル(存在する場合)が表示されます。

ls src/components/App
OutputApp.css         App.js          App.test.js
ls src/components/Instructions
OutputInstructions.css        Instructions.js         emoji.svg

この時点で、プロジェクトの堅固な構造が作成されました。 多くのコードを移動しましたが、構造ができたので、スケーリングが簡単になります。

これは、構造を構成する唯一の方法ではありません。 一部のファイル構造では、異なるパッケージに分割されるディレクトリを指定することにより、コード分割を利用できます。 その他のファイル構造はrouteで分割され、ルート間で使用されるコンポーネントに共通のディレクトリを使用します。

今のところ、それほど複雑ではないアプローチに固執します。 別の構造の必要性が明らかになると、単純なものから複雑なものへの移行が常に容易になります。 必要になる前に複雑な構造から始めると、リファクタリングが困難になります。

クラスベースのコンポーネントを作成して整理したので、次のステップで機能コンポーネントを作成します。

ステップ4—機能コンポーネントの構築

このステップでは、機能コンポーネントを作成します。 機能コンポーネントは、現代のReactコードで最も一般的なコンポーネントです。 これらのコンポーネントは短くなる傾向があり、クラスベースのコンポーネントとは異なり、新しい形式の状態およびイベント管理であるReactフックを使用できます。

機能コンポーネントは、JSXを返すJavaScript関数です。 何も拡張する必要はなく、覚える特別な方法もありません。

<Instructions>を関数コンポーネントとしてリファクタリングするには、クラスを関数に変更し、renderメソッドを削除して、returnステートメントのみが残るようにする必要があります。

これを行うには、最初にテキストエディタでInstructions.jsを開きます。

nano src/components/Instructions/Instructions.js

class宣言をfunction宣言に変更します。

チュートリアル-03-component/src / components / Instructions / Instructions.js

import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

次に、{ Component }のインポートを削除します。

チュートリアル-03-component/src / components / Instructions / Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

最後に、render()メソッドを削除します。 その時点では、JSXのみを返しています。

チュートリアル-03-component/src / components / Instructions / Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  return(
    <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
    </div>
  )
}

ファイルを保存します。 ブラウザが更新され、以前と同じようにページが表示されます。

暗黙の戻り値を使用して、関数を矢印関数として書き直すこともできます。 主な違いは、関数本体が失われることです。 また、最初に関数を変数に割り当ててから、変数をエクスポートする必要があります。

チュートリアル-03-component/src / components / Instructions / Instructions.js

import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

const Instructions = () => (
  <div className="instructions">
    <img alt="laughing crying emoji" src={emoji} />
    <p>Click on an emoji to view the emoji short name.</p>
  </div>
)

export default Instructions;

単純な機能コンポーネントとクラスベースのコンポーネントは非常に似ています。 状態を保存しない単純なコンポーネントがある場合は、機能コンポーネントを使用するのが最適です。 2つの本当の違いは、コンポーネントの状態を保存し、プロパティを使用する方法です。 クラスベースのコンポーネントは、メソッドとプロパティを使用して状態を設定し、少し長くなる傾向があります。 機能コンポーネントはフックを使用して状態を保存したり、変更を管理したりするため、少し短くなる傾向があります。

結論

これで、独立した部分を持つ小さなアプリケーションができました。 機能とクラスの2つの主要なタイプのコンポーネントを作成しました。 コンポーネントの一部をディレクトリに分割して、類似したコードをグループ化しておくことができるようにしました。 また、コンポーネントをインポートして再利用しました。

コンポーネントを理解すると、アプリケーションを分解して元に戻すことができる部分として見ることができます。 プロジェクトはモジュール化され、交換可能になります。 アプリケーション全体を一連のコンポーネントとして見ることができることは、Reactで考える上で重要なステップです。 その他のReactチュートリアルをご覧になりたい場合は、 Reactトピックページをご覧になるか、React.jsシリーズのコーディング方法ページに戻ってください。