Reactでコンポーネントロジックを共有する3つの方法

Reactでコンポーネントロジックを共有する3つの方法

簡単に説明すると、これら 3 つの方法は、レンダリング プロップ、高階コンポーネント、カスタム フックです。以下は

次のように、ユーザーが現在のページに滞在する時間を記録する専用の TimeOnPage コンポーネントがあるとします。

定数TimeOnPage = () => {
 定数[秒、setSecond] = useState(0);

 使用効果(() => {
  タイムアウトを設定する(() => {
   setSecond(秒 + 1);
  }, 1000);
 }、 [2番]);
 戻る (
  <div>滞留時間: {second} 秒</div>
 );
}

別のコンポーネントでこの機能を再利用する必要がある場合、他のコンポーネントと簡単に共有できるようにカプセル化できますか?

ネストされたサブコンポーネントを考え、プロパティを使用してパラメータを渡すのは自然なことです。

const 子 = (props) => {
 <div>stayTime: {props.stayTime}s</div> を返します。
};

定数TimeOnPage = () => {
 定数[秒、setSecond] = useState(0);

 使用効果(() => {
  タイムアウトを設定する(() => {
   setSecond(秒 + 1);
  }, 1000);
 }、 [2番]);
 戻る (
  <div>
   <子の滞在時間={秒} />
  </div>
 );
}

これは TimeOnPage コンポーネント内にハードコードされており、カプセル化と再利用の目標はまだ達成されていません。レンダリング プロップがどのように機能するかわかりますか?

レンダリングプロップ

「レンダリング プロップ」とは、値が関数であるプロップを使用して React コンポーネント間でコードを共有するシンプルな手法を指します。

前回の記事に引き続き、TimeOnPage で関数値を持つプロパティを定義します。コンポーネントをレンダリングする場合は、関数内でそれを返すだけです。関数のパラメーターは、共有したい状態です。

const 子 = (props) => {
 <div>stayTime: {props.stayTime}s</div> を返します。
};

const TimeOnPage = (props) => {
 定数[秒、setSecond] = useState(0);

 使用効果(() => {
  タイムアウトを設定する(() => {
   setSecond(秒 + 1);
  }, 1000);
 }、 [2番]);
 <div>{props.render(second)}</div> を返します。
};

<TimeOnPage レンダリング ={(stayTime) => <Child stayTime ={stayTime} />

実際、レンダリング プロップは、どのコンテンツをレンダリングする必要があるかをコンポーネントに伝えるために使用される関数プロップです。
React Router もこのテクニックを使用します。

<ルーター>
 <Route path="/home" render={() => <div>ホーム</div>} />
</ルーター>

高階コンポーネント

高階コンポーネント (HOC) は、React でコンポーネント ロジックを再利用する高度な手法です。 HOC 自体は React API の一部ではなく、React の構成特性に基づいた設計パターンです。

高階コンポーネントとは、再利用する必要があるコンポーネント A をパラメーターとし、戻り値が新しいコンポーネント N である関数です。新しいコンポーネント N はコンポーネント A に基づいて処理されますが、コンポーネント A 自体は変更されず、機能のみが強化されます。

次のようなニュース リスト コンポーネントがあるとします。

定数NewList = () => {
 戻る (
  <div>
   <ul>
    <li>ニュース記事</li>
    <li>ニュース記事</li>
   </ul>
  </div>
 );
}

ニュースリストの読み込み中に読み込みアニメーションコンポーネント<Loading />を表示したい場合は、通常次のようにします。

const 読み込み = () => {
 // アニメーションの読み込み}
const NewList = ({ isLoading }) => {
 isLoading を返します? (
  <読み込み中 />
 ) : (
  <div>
   <ul>
    <li>ニュース記事</li>
    <li>ニュース記事</li>
   </ul>
  </div>
 );
};

テーブルコンポーネントでも、同様のパターンに従って、データの読み込み中に読み込みアニメーションコンポーネントを表示したいとします。

const 読み込み = () => {
 // アニメーションの読み込み}
const DataList = ({ isLoading, ...props }) => {
 isLoading を返します? (
  <読み込み中 />
 ) : (
  <テーブル {...props} />
 );
};

上記から、DataList と NewList の構造が非常に似ていることがわかります。ロードする 3 番目と 4 番目のコンポーネントがある場合、このパターンを 3 回目と 4 回目に繰り返し続けるのでしょうか?これは最も理想的なアプローチではありません。より良いアプローチは、高階コンポーネントを使用してこのパターンを抽象化することです。

const WithLoading = (WrappedComponent) => {
 戻り値 ({isLoading, ...props}) => {
  isLoading を返します。<Loading />: <WrappedComponent {...props} />;
 }
};

その後、NewListとDataListを変更せずに、個別にロードを追加できます。

定数NewList = () => {
 戻る (
  <div>
   <ul>
    <li>ニュース記事</li>
    <li>ニュース記事</li>
   </ul>
  </div>
 );
};

const DataList = (props) => {
 <Table {...props} /> を返します。
};

const WithLoading = (WrappedComponent) => {
 戻り値 ({isLoading, ...props}) => {
  isLoading を返します。<Loading />: <WrappedComponent {...props} />;
 }
};
// 読み込み中の NewList
定数 WithLoadingNewList = WithLoading(<NewList />)
// 読み込み中の DataList
const WithLoadingDataList = WithLoading(<DataList />)

カスタムフック

フックは React 16.8 の新機能です。クラスを記述せずに状態やその他の React 機能を使用できるようになります。

React フックには、useState、useEffect などが含まれます。これらはすべて関数です。カスタム フックも関数です。その名前も use で始まります。他のフックは関数内で呼び出すことができます。 React コンポーネントとは異なり、カスタムフックは値を返す必要はありません。通常の関数とは異なり、カスタム フックは他のフックを呼び出すことができますが、通常の関数は呼び出すことができません。

ビジネス ロジックを記述する場合、再利用可能なメソッドの一部は一般にツール関数として定義され、どこでも再利用できます。同様に、フックをカスタマイズすることで、コンポーネント ロジックを再利用可能な関数に抽出できます。カスタム フックを選択するかツール関数を選択するかは、抽出するコンポーネント ロジックに他のフックが必要かどうかによって決まります。必要な場合はカスタム フックを選択し、そうでない場合はツール関数を使用します。

この記事の最初のTimeOnPageコンポーネントに戻り、カスタムフックに変更します。

定数useTimeOnPage = () => {
 定数[秒、setSecond] = useState(0);

 使用効果(() => {
  タイムアウトを設定する(() => {
   setSecond(秒 + 1);
  }, 1000);
 }、 [2番]);
 2番目を返します。
}

使い方

constデモ = () => {
 const stayTime = useTimeOnPage();
 <div>現在のページの滞在時間: {stayTime} 秒</div> を返します。
}

要約する

コンポーネント ロジックを共有する 3 つの方法には、それぞれ適用可能なシナリオがあります。
レンダリング プロップは、親コンポーネントを異なるサブコンポーネント/サブ要素と共有するのに適しています。サブコンポーネント/サブ要素の「ピット」が定義されており、指定された位置にのみレンダリングできます。
高階コンポーネントは、元のコンポーネントを変更せずにコンポーネントを拡張するのに適しています。
純粋関数は基本的にカスタムフックと同じ機能を実行できますが、カスタムフックを使用する方が便利で高速な場合もあります。
この記事へのリンク: Github

これで、React でコンポーネント ロジックを共有する 3 つの方法についての記事は終了です。React の共有コンポーネント ロジックに関する詳細なコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • React コンポーネントのリファクタリング: ネスト + 継承と高階コンポーネントの説明
  • Reactにおけるネストされたコンポーネントとネストされたコンポーネント間の通信プロセス
  • 簡潔なReactコンポーネントを書くためのヒント
  • フックを使用して React コンポーネントを書くときに注意すべき 5 つの点
  • Reactはラジオコンポーネントのサンプルコードを実装します
  • ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法を詳しく説明します
  • Reactフックとzarmコンポーネントライブラリ構成に基づいてh5フォームページを開発するためのサンプルコード
  • React antd タブの切り替えによりサブコンポーネントが繰り返し更新される
  • react-antd でポップアップ フォームのコンテンツを親コンポーネントに渡す方法
  • Reactプロジェクトでantdのフォームコンポーネントを使用して、入力ボックスの値を動的に設定する
  • Reactにおけるコンポーネントロジックの再利用についての簡単な説明
  • React のネストされたコンポーネントの構築順序

<<:  MySQL 5.7.17 インストール グラフィック チュートリアル (Windows)

>>:  Centos7 に PHP と Nginx をインストールする詳細なチュートリアル

推薦する

MySQL でデータの重複挿入を回避する 4 つの方法

最も一般的な方法は、フィールドに主キーまたは一意のインデックスを設定することです。重複データを挿入す...

XHTML におけるタイトルタグと段落タグの使用に関する詳細な説明

XHTML 見出しの概要Word 文書を作成するときは、「第 1 章」、「1.2.1」などのタイトル...

dockerプライベート倉庫の構築と利用の詳細説明

1. リポジトリイメージをダウンロードする docker プルレジストリ 2. プライベートウェアハ...

MySQL の無効な左結合の問題を解決する方法とその使用上の注意

MySQLの左結合が無効であり、その使用方法今日SQLを書いていたとき、左結合を使用すると左のテーブ...

JavaScript を使用せずに HTML の a タグを無効にするには、純粋な CSS を使用します。

実際、この問題は、HTML の select タグを初めて学んだときにすでに発生していました。今日に...

JSはストップウォッチタイマーを実装します

この記事の例では、ストップウォッチタイマーを実装するためのJSの具体的なコードを参考までに共有してい...

グリーンスタイルのウェブデザイン作品18点の最新コレクション

トイ・ストーリー3 オンラインマーケティングウェブサイトゼンモバイル鉄から鉄へスプラウトファンドバー...

MySQLの高可用性と高パフォーマンスのクラスタを構築する方法

目次MySQL NDB Clusterとはクラスター構築のための準備作業クラスターのデプロイを開始す...

Websocket+Vuexはリアルタイムチャットソフトウェアを実装します

目次序文1. 効果は図の通りです2. 具体的な実施手順1. Vuexの紹介2.webscoked実装...

Centos7 に PHP と Nginx をインストールする詳細なチュートリアル

Centos のサーバー側への適用がますます普及するにつれて、Centos7 もますます使用されるよ...

WeChatミニプログラムページで値を返す4つの解決策のまとめ

目次使用シナリオ解決1. globalDataを使用して実装する2. ローカルキャッシュストレージを...

HTMLは角丸四角形を簡単に実装します

質問: div+css と配置を使用して角丸四角形を実現するにはどうすればよいですか?ソリューション...

DockerプライベートイメージライブラリとAlibaba CloudオブジェクトストレージOSSの簡単な分析

Docker プライベートイメージライブラリDockerプライベートイメージライブラリとAlibab...

Linux に起動方法を追加する (サービス/スクリプト)

システムの起動時に読み込む必要がある設定ファイル/etc/profile、/root/.bash_p...

Linuxの運用・保守の基礎知識から上級者向け知識までをまとめました

運用保守エンジニアは、初期段階では非常に大変な仕事です。この期間中、コンピューターの修理、ネットワー...