著者は、 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を使用してプロジェクトのベースを作成します。 また、デフォルトのプロジェクトを変更して、絵文字のリストにマッピングし、少量のスタイルを追加して、ベースプロジェクトを作成します。

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

  1. npx create-react-app tutorial-03-component

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

  1. cd tutorial-03-component

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

  1. 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構文を使用して map()を介して emojis arrayそしてそれらを次のようにリストします <li> アイテムを一覧表示します。 付属します onClick events は、ブラウザに絵文字データを表示します。 コードの詳細については、JSXの詳細な説明が含まれているJSXを使用してReact要素を作成する方法を確認してください。

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

  1. rm src/logo.svg

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

  1. 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要素を作成する方法を参照してください。

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

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

  1. npm start

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

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

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

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

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

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

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

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

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

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

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

  1. touch src/Instructions.js

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

  1. nano src/Instructions.js

まず、インポート React そしてその Component クラスとエクスポート Instructions 次の行で:

チュートリアル-03-component/src / Instructions.js
import React, { Component } from 'react';

export default class Instructions extends Component {}

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

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

本拠 Component クラスには、カスタムクラスで使用できるいくつかのメソッドがあります。 最も重要な方法であり、このチュートリアルで使用する唯一の方法は、 render() 方法。 The 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 テキストエディタの場合:

  1. 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;

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

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

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

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

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

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

  1. 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に変更し、それに classNameinstructions:

チュートリアル-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:

  1. 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;
}

追加すると displayflex スタイリング、あなたは img そしてその p flexboxを中心にしています。 すべてが垂直に並ぶように方向を変更しました flex-direction: column;. この線 align-items: center; 画面上の要素を中央に配置します。

要素が揃ったので、画像サイズを変更する必要があります。 与える imgdiv a widthheight100px.

チュートリアル-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;
}

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

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

開ける App.js:

  1. 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回表示されます。

この場合、次の2つのインスタンスは必要ありません。 Instructions、しかし、コンポーネントを効率的に再利用できることがわかります。 カスタムボタンまたはテーブルを作成する場合、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>. また、CSSコードを混合しています <App> CSSを使用して <Instructions>.

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

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

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

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

  1. ls src/

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

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

あなたはのためのコードを持っています <App> 成分 (App.css, App.js、 と App.test.js)ルートコンポーネントの横に座っている(index.cssindex.js)およびカスタムコンポーネント Instructions.js.

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

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

の作成 Components ディレクトリ

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

  1. mkdir src/components

次に、次のコンポーネントとコードをディレクトリに移動します。 App.css, App.js, App.test.js, Instructions.js、 と emoji.svg:

  1. mv src/App.* src/components/
  2. mv src/Instructions.js src/components/
  3. mv src/emoji.svg src/components/

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

コードを移動すると、実行中のターミナルにエラーが表示されます npm start.

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

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

そのためには、 index.js.

  1. 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サービス、データストア、およびユーティリティ関数用のディレクトリが作成される場合があります。 コンポーネントコードを分離することが最初のステップですが、CSSコードはまだあります Instructions に混合 App.css ファイル。 この論理的な分離を作成するには、最初にコンポーネントを別々のディレクトリに移動します。

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

まず、専用のディレクトリを作成します <App> 成分:

  1. mkdir src/components/App

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

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

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

Output
Failed 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 ファイル:

  1. nano src/index.js

次に、アプリのインポートパスを更新して、 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();

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

Output
Failed 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. と呼ばれるディレクトリを作成します Instructions の中に src/components ディレクトリ:

  1. mkdir src/components/Instructions

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

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

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

更新 import パス

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

開ける App.js:

  1. nano src/components/App/App.js

パスは相対パスであるため、1つのディレクトリを上に移動する必要があります—src/components-次に、 Instructions のディレクトリ Instructions.js、ただし、これは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/components/App/index.js の中に src/index.js ファイルは import ./components/App. このアプローチの欠点は、同じ名前のファイルがたくさんあることです。これにより、一部のテキストエディタで読みにくくなる可能性があります。 最終的には、個人およびチームの決定ですが、一貫性を保つことが最善です。

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

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

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

  1. touch src/components/Instructions/Instructions.css

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

  1. 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.

  1. 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:

  1. 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/ ディレクトリ:

  1. ls src

ルートコンポーネントがあります index.js および関連するCSS index.css のそばに components/ ディレクトリやユーティリティファイルなど serviceWorker.jssetupTests.js:

Output
components serviceWorker.js index.css setupTests.js index.js

次に、中を見てください components:

  1. ls src/components

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

Output
App Instructions

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

  1. ls src/components/App
Output
App.css App.js App.test.js
  1. ls src/components/Instructions
Output
Instructions.css Instructions.js emoji.svg

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

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

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

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

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

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

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

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

そのためには、最初に開きます Instructions.js テキストエディタで。

  1. 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シリーズのコーディング方法ページに戻ってください。