Reactのコンポーネント共同利用実装

Reactのコンポーネント共同利用実装

開発者は、UI レベルでの実装の詳細にあまり注意を払う必要はありません。最も考慮する必要があるのは、コンポーネント間のデータ通信です。では、React 開発では、コンポーネントが連携して動作するシナリオにはどのようなものがあるでしょうか?コンポーネントの協調的な使用を実現するにはどうすればよいでしょうか?

コンポーネントコラボレーションは、本質的にはコンポーネントを整理および管理する方法です。

目的は、システム ロジックを明確にし、コードをモジュール化し、詳細をカプセル化し、コードを再利用可能にすることです。

コンポーネントのコラボレーションには、ネスト、抽出、パブリッシュ/サブスクライブ モードの 2 つの方法があります。

ネスティング

コンポーネントのネストの本質は親子関係、つまり親コンポーネントと子コンポーネント間の通信です。

一般的に、次の 2 つのシナリオがあります。

  • 親子コンポーネント通信
  • ブラザーコンポーネント通信

親子コンポーネント通信

まず、props 属性を使用した最もよく使用される方法を見てみましょう。親子コンポーネントを例にとると、親コンポーネントは props の形式で子コンポーネントにデータを渡すだけで、子コンポーネントは this.props を通じてそれを直接取得できます。次に例を示します。

// 親コンポーネント
デフォルトのクラスをエクスポートし、親クラスをReact.Componentに拡張します。
  コンストラクタ(props) {
    スーパー(小道具);

    この状態 = {
      メッセージ: '子コンポーネントに渡されたメッセージ'
    }
  }

  //メッセージコールバック onMessage(messageFromChildren) {
    console.log(子供からのメッセージ);
  }

  与える() {
    const { メッセージ } = this.state;
    戻る (
      <div>
        <子メッセージ={メッセージ} onMessage={this.onMessage.bind(this)} />
      </div>
    );
  }
}
//子供たち
デフォルトのクラスChildrenをエクスポートし、React.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
  }

  ハンドルクリック() {
    this.props.onMessage('子コンポーネントからのメッセージ');
  }

  与える() {
    const { メッセージ } = this.props;
    戻る (
      <div>
        <p>{メッセージ }</p>
        <button onClick={ this.handleClick.bind(this) }>クリック</button>
      </div>
    );
  }
}

もちろん、子コンポーネントが親コンポーネントにデータを渡す必要がある場合は、コールバック メソッドを使用できます。親コンポーネントは、上記のコードで handleClick の onMessage を呼び出すなど、props を通じてメソッドの参照を子コンポーネントに渡します。親コンポーネントの状態が更新されると、子コンポーネントは再レンダリングされ、最新のメッセージ データが使用されます。

bind の機能は、関数にデフォルトのパラメータを追加することです。メソッド内の最初のパラメータがこれを置き換えます。

ブラザーコンポーネント通信

兄弟コンポーネントは直接通信することができないため、ステータスを改善するには親コンポーネントを介して転送する必要があります。兄弟コンポーネントは、共有する必要があるデータを共通の直接の親コンポーネントに昇格し、通常の親子コンポーネントと同様に相互に通信します。例えば:

// 親コンポーネント
デフォルトのクラスをエクスポートし、親クラスをReact.Componentに拡張します。
  コンストラクタ(props) {
    スーパー(小道具);

    この状態 = {
      メッセージ送信者A: ''、
      メッセージFromB: ''
    }
  }

  onMessage(messageFromChildren, from) {
    console.log(子供からのメッセージ);

    this.setState({
      [from == 'A' ? 'messageFromA' : 'messageFromB']: messageFromChildren
    });
  }

  与える() {
    定数{messageFromA, messageFromB} = this.state;
    戻る (
      <div>
        <ChildrenA message={ messageFromB } onMessage={ this.onMessage.bind(this) } />
        <ChildrenB message={ messageFromA } onMessage={ this.onMessage.bind(this) } />
      </div>
    );
  }
}
//子供A
デフォルトのクラスChildrenAをエクスポートし、React.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
  }

  ハンドルクリック() {
    this.props.onMessage('Aサブコンポーネントからのメッセージ', 'A');
  }

  与える() {
    const { メッセージ } = this.props;
    戻る (
      <div className="pa ba">
        <p>{メッセージ }</p>
        <button onClick={this.handleClick.bind(this)}>クリックA</button>
      </div>
    );
  }
}
//子供B
デフォルトのクラスChildrenBをエクスポートし、React.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
  }

  ハンドルクリック() {
    this.props.onMessage('B 子コンポーネントからのメッセージ', 'B');
  }

  与える() {
    const { メッセージ } = this.props;
    戻る (
      <div className="pa ba">
        <p>{メッセージ }</p>
        <button onClick={this.handleClick.bind(this)}>Bをクリック</button>
      </div>
    );
  }
} 

clickA がクリックされると、サブコンポーネント B はサブコンポーネント A からメッセージを受信し、その逆も同様です。

props を介したコンポーネント通信は比較的簡単ですが、独自の欠点もあります。コンポーネント レベルが 3 層を超える場合、この方法は適していません。まず、深いレベルの伝送はメンテナンスにとって悪夢です。データのソースとフローを把握するには、各レイヤーを確認する必要があります。次に、サブコンポーネント A と B だけでなくサブコンポーネント C もある場合、コンポーネント A と B による親コンポーネントの状態更新によってサブコンポーネント C の更新がトリガーされますが、実際にはサブコンポーネント C はデータを受信しないため、リソースの無駄が簡単に発生する可能性があります。

// 親コンポーネントのrender() {
    定数{messageFromA, messageFromB} = this.state;
    戻る (
      <div>
        <ChildrenA message={ messageFromB } onMessage={ this.onMessage.bind(this) } />
        <ChildrenB message={ messageFromA } onMessage={ this.onMessage.bind(this) } />
        <子供達C />
      </div>
    );
  }
//子供C
デフォルトのクラスChildrenCをエクスポートし、React.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
  }

  コンポーネントを更新しました() {
    console.log('ChildrenCが更新されました');
  }


  与える() {
    戻る (
      <div>子供C</div>
    );
  }
}

撤回する

ミキシン

ここで紹介する抽出は主にMixinに関するものです。

複数のコンポーネントが同じ getDefaultProps メソッドを使用すると仮定すると、次の Mixin を定義できます。

var デフォルト名ミックスイン = {
    getDefaultProps: 関数 () {
        {name: "トム"} を返します。
    }
};

Mixin はコンポーネントの拡張機能に相当します。その本質はメソッドのコレクションです。この Mixin を使用するコンポーネントは、これらのメソッドを自由に使用できます (コンポーネントで定義されているとおりに)。 Mixin を使用する目的は、コンポーネントの類似コードを水平に抽出することです。

Mixin に似た他の概念には、AOP、プラグインなどがあります。

この例では、DefaultNameMixin に getDefaultProps メソッドが含まれています。直接定義に加えて、Mixin はネストすることもできます。つまり、Mixin を定義するときに別の Mixin を使用できます。

var デフォルトコモンミックスイン = {
    mixins:[DefaultNameMixin], //Mixinを使用する
    getDefaultProps: 関数 () {
        {food: "米"} を返します。
    }
};

この例では、DefaultNameMixin が DefaultCommonMixin の定義内にネストされているため、DefaultCommonMixin には DefaultNameMixin で定義されている getDefaultProps メソッドが含まれます。この時点で、DefaultCommonMixin には 2 つのメソッドがあります。 Mixin を使用する場合は、mixins 属性に対応する配列に Mixin を追加するだけです。Mixin を使用するための構文は、mixins:[Mixin1, Mixin2…] です。

Mixin を使用する場合は、mixins 属性に対応する配列に Mixin を追加するだけです。Mixin を使用するための構文は、mixins:[Mixin1, Mixin2…] です。

var コンポーネント = React.createClass({
    mixins:[DefaultCommonMixin], //Mixinを使用する
    レンダリング:関数(){
        <h1>{this.props.name} を {this.props.food} のように返します。
    }
}); 

ReactDOM.render() は、
    <コンポーネント/>、
    document.getElementById("例")
);

コンポーネントは複数の Mixin を使用でき、Mixin も複数のコンポーネントで使用できます。

Mixin を使用する場合は、同じ Prop と State を複数の場所に設定しないように注意してください。同時に、異なる Mixin に同じメソッドが定義されている場合、または Mixin とコンポーネントに同じメソッドが含まれている場合は、例外がスローされます。ただし、componentDidMount などのライフサイクル メソッドにはこの状況は当てはまりません (render メソッドは例外で、複数回定義されている場合にも例外がスローされます)。

コンポーネント内の複数の場所で同じライフサイクル メソッドが定義されている場合、これらのメソッドの実行順序は次のようになります。まず、ミックスイン内のメソッドが実行され (ミックスイン内の順序に従って左から右へ)、次にコンポーネントで定義されたメソッドが実行されます。

Mixin の利点:

コードの再利用: 共通コードを抽出し、開発コストを削減し、開発効率を向上します

プラグアンドプレイ: 既存の多くのMixinを直接使用して独自のコンポーネントを作成できます。

高い適応性: コードを一度変更すると、複数のコンポーネントに影響します。

Mixin の欠点:

高い記述難易度: Mixin はさまざまな環境で使用される可能性があります。複数の環境との互換性には、より多くのロジックとコードが必要です。普遍性のコストは複雑さの増加です。

コードの可読性の低下: コンポーネントの利点は、ロジックとインターフェースを直接組み合わせることです。Mixin は基本的にロジックを分散させ、理解しにくくなります。

React の LinkedStateMixin

'厳密な使用';  
  
// オブジェクト {value, requestChange} を構築します。value は初期値、requestChange は手動で呼び出す必要があるメソッドです。// このモジュールでは、value は state[key] の初期値、requestChange は state[key] を更新するために使用されます。  
var ReactLink = require('./ReactLink');  
  
// 属性キーを設定した後、値を受け入れ、内部でcomponent.setStateメソッドを呼び出してstate[key]=valueを更新する関数を返します。  
var ReactStateSetters = require('./ReactStateSetters');  
  
/** 
 * react で setState メソッドを手動で呼び出す一方向のデータフローに双方向バインディングを提供します。 * linkState(key).requestChange(value) を使用して値を渡した後、setState メソッドを自動的に呼び出して状態を更新します。 
 * 
 * 例 * var LinkedStateMixin = require('react-addons-linked-state-mixin'); 
 
 * var WithoutLink = React.createClass({ 
 * ミックスイン: [LinkedStateMixin], 
 * 初期状態を取得する: 関数() { 
 * {メッセージ: 'Hello!'} を返します。 
 * }, 
 * レンダリング: 関数() { 
 * var valueLink = this.linkState('message'); 
 * var handleChange = function(e) { 
 * valueLink.requestChange(e.target.value); 
 * }; 
 * <input type="text" value={valueLink.value} onChange={handleChange} /> を返します。 
 * } 
 * }); 
 */  
var リンクステートミックスイン = {  
  // ReactStateSetters.createStateKeySetter メソッドは、linkState(key) によって返されるオブジェクトの requestChange メソッドを構築するために使用されます。// 値を渡した後、setState メソッドを自動的に呼び出して状態を更新します。  
  リンクステート: 関数 (キー) {  
    新しい ReactLink(this.state[key], ReactStateSetters.createStateKeySetter(this, key)) を返します。  
  }  
};  
  
モジュールをエクスポートします。

上記のミックスインを使用します:

'react-addons-linked-state-mixin' から LinkedStateMixin をインポートします。

ミックスイン: [React.addons.LinkedStateMixin],

LinkedStateMixin onChange/setState()パターンの単純なラッパーと規則です。 Reactアプリケーションでのデータ フローを根本的に変更するものではありません。言い換えると、 LinkedStateMixin本質的に一方向のフローです。データの変更をonChangeを通じてReactに渡し、その後自動的にsetStateを呼び出して内部データを更新するだけです。

使用例:

var WithLink = React.createClass({
  ミックスイン: [LinkedStateMixin],
  初期状態を取得する: 関数() {
    {メッセージ: 'こんにちは!'} を返します。
  },
  レンダリング: 関数() {
    <input type="text" valueLink={this.linkState('message')} /> を返します。
  }
});

LinkedStateMixinReactコンポーネントにlinkState()というメソッドを追加します。 linkState() React stateの現在の値とそれを変更するためのコールバック関数を含むvalueLinkオブジェクトを返します。

valueLinkオブジェクトは、 propsとしてツリーの上下に渡すことができるため、コンポーネント レベルと状態レベルで双方向バインディングを確立するのは非常に簡単です。

知らせ:

checkboxvalue属性には特別な動作があります。 checkboxが選択されている場合 (デフォルトではon )、フォームが送信されるとvalue属性値が送信されます。 checkboxがオンまたはオフになっている場合、 value属性は更新されません。 checkboxの場合は、 valueLinkではなくcheckLink使用する必要があります。

<チェックボックス type="checkbox" チェックされたリンク = {this.linkState('booleanValue')} />

参照:

1. http://schifred.iteye.com/blog/2361478

2. http://blog.csdn.net/qq_18661257/article/details/68951561

Reactコンポーネントの連携利用に関する記事はこれで終了です。Reactコンポーネント連携に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Reactでコンポーネントを作成する方法
  • Reactは動的ポップアップウィンドウコンポーネントを実装します
  • React 星評価コンポーネントの実装

<<:  Linux で静的ルーティングを追加するための 2 つの実装方法の分析

>>:  MySQL 単一テーブルクエリの例の詳細な説明

推薦する

製品を選択した後、右下隅に√記号を表示するための純粋なCSS

おすすめの記事: CSS 疑似クラスの右下隅をクリックすると、選択を示すチェックマークが表示されます...

React+axios は github 検索ユーザー機能を実装します (サンプル コード)

負荷リクエスト成功リクエストに失敗しました cmdをクリックし、ファイルパスでEnterキーを押しま...

MySQLの整数および文字列インデックスの無効化または暗黙的な変換に関する簡単な説明

目次問題の概要問題の再現問題の拡大結論は問題の概要今日、仕事中に、DBA が突然、SQL に暗黙的な...

Vueを使用して天気コンポーネントをロードする方法の詳細な説明

この記事では、Vueを使用して天気コンポーネントをロードする方法を参考までに紹介します。具体的な内容...

OpenLayers 3 のベクターマップソースの読み込みの問題を解決する

1. ベクターマップベクター グラフィックスは直線と曲線を使用してグラフィックスを表します。これらの...

html の img src="" で js 関数または js 変数を呼び出して、画像パスを動的に指定します。

この問題に関して、オンライン リソースをたくさん見つけました。ここにいくつかの方法を示します。コード...

MySQLのグループカウントと範囲集計を実装する2つの方法

1つ目:通常動作 選択 SUM(ddd) AS count_days、 場合 aa.days >...

vue+springbootでログイン認証コードを実現

この記事では、ログイン認証コードを実装するためのvue+springbootの具体的なコードを例とし...

列名を知らなくてもMySQLインジェクションを詳細に解説

序文最近、穴を掘ってスペースを作っているだけなので、心が空っぽになっているように感じます。テクノロジ...

MySQL フラッシュリストとダーティページフラッシュメカニズム

1. レビューMySQL の起動後にバッファ プールが初期化されます。バッファ プールは N 個の空...

Nginx の break と last の違いの詳細な分析

まずは違いについて話しましょう最後に、書き換えられたルールは、次の場所と一致させるために書き換えられ...

MySQL 8.0.11 MSI バージョンのインストールと構成のグラフィック チュートリアル

この記事では、MySQL 8.0.11 MSIバージョンのインストールと設定のチュートリアルを参考ま...

Nginx SSL証明書設定エラーの解決策

1. はじめにWeb プロジェクトを Linux サーバーで公開する場合、SSL 証明書を構成する必...

CocosCreatorでWeChatゲームを作成する方法

目次1. WeChatパブリックプラットフォームからWeChat開発者ツールをダウンロードする2. ...

要素 el-table テーブルの二次カプセル化 (テーブルの高さの調整付き)

序文会社でのインターンシップ中、フロントエンド開発にはvue+element-uiフレームワークを使...