ホームページ  >  記事  >  ウェブフロントエンド  >  React の高度なコンポーネントとは何ですか? React の高度なコンポーネントの詳細な説明

React の高度なコンポーネントとは何ですか? React の高度なコンポーネントの詳細な説明

不言
不言オリジナル
2018-09-14 13:55:302252ブラウズ

この記事では、React の高度なコンポーネントとは何ですか? React の高度なコンポーネントの詳細な説明は、必要としている友人が参考にできることを願っています。

1. 基本概念

高度な関数は、関数をパラメータとして受け取り、関数を返す関数です。同様に、高次コンポーネント (略して HOC) は React コンポーネントをパラメーターとして受け取り、新しい React コンポーネントを返します。高次コンポーネントは本質的にはコンポーネントではなく関数です。上位コンポーネントの関数形式は次のとおりです。

const EnhanceComponent = higherOrderComponent(WrappedComponent)

上位コンポーネントがどのように再利用されるかを簡単な例で説明します。ここには、LocalStorage からデータを取得してインターフェイスにレンダリングする必要があるコンポーネント MyComponent があります。通常の状況では、次のように実装できます。

import React, { Component } from 'react'

class MyComponent extends Component {
  componentWillMount() {
    let data = localStorage.getItem('data');
    this.setState({data});
  }
  render() {
    return(
      <div>{this.state.data}</div>
    )
  }
}

コードは非常に単純ですが、他のコンポーネントも LocalStorage から同じデータを取得して表示する必要がある場合、各コンポーネントは、componentWillMount のコードを書き直す必要があります。これは明らかに非常に冗長です。高次コンポーネントを使用してコードのこの部分を書き直す方法を見てみましょう。

import React, { Component } from 'react'

function withPersistentData(WrappedComponent) {
  return class extends Component {
    componentWillMount() {
      let data = localStorage.getItem('data');
      this.setState({data});
    }
    render() {
      // 通过{ ...this.props} 把传递给当前组件属性继续传递给被包装的组件
      return <WrappedComponent data={this.state.data} {...this.props}/>
    }
  }
}

class MyComponent extends Component{
  render() {
    return <p>{this.props.data}</p>
  }
}

const MyComponentWithPersistentData = withPersistentData(MyComponent);

withPersistentData は、新しいコンポーネントを返す上位コンポーネントです。新しいコンポーネントでは、componentWillMount が LocalStorage からデータを取得するロジックを処理し、取得したデータを WrappedComponent を通じてパッケージ化されたコンポーネントに渡します。これにより、WrappedComponent で this.props.data を直接使用して、表示する必要があるデータを取得できるようになります。他のコンポーネントでもこのロジックが必要な場合は、引き続き上位コンポーネント withPersistentData を使用してこれらのコンポーネントをラップします。

2. 使用シナリオ

上位コンポーネントの使用シナリオには主に次の 4 つが含まれます:
1) props の操作
2) ref を介したコンポーネント インスタンスへのアクセス
3) コンポーネントのステータスの改善
4) コンポーネントを他の要素でラップする

1. props を操作する

ラップされたコンポーネントが props を受け取る前に、上位コンポーネントが最初に props をインターセプトし、props を追加することができます。 、操作を削除または変更し、処理された props をラップされたコンポーネントに渡します。1 の例は、この状況に属します。

2. ref を介してコンポーネント インスタンスにアクセスする

上位コンポーネント ref は、パッケージ化されたコンポーネント インスタンスの参照を取得し、上位コンポーネントはプロパティを直接操作する機能を持ちます。またはパッケージ化されたコンポーネントのメソッド。

import React, { Component } from 'react'

function withRef(wrappedComponent) {
  return class extends Component{
    constructor(props) {
      super(props);
      this.someMethod = this.someMethod.bind(this);
    }

    someMethod() {
      this.wrappedInstance.comeMethodInWrappedComponent();
    }

    render() {
      // 为被包装组件添加 ref 属性,从而获取组件实例并赋值给 this.wrappedInstance
      return <wrappedComponent ref={(instance) => { this.wrappedInstance = instance }} {...this.props}/>
    }
  }
}

wrapComponent がレンダリングされると、ref のコールバック関数が実行され、上位コンポーネントは this.wrappedInstance を通じて WrappedComponent インスタンスの参照を保存し、someMethod の this.wrappedInstance を通じて WrappedComponent 内のメソッドを呼び出します。この使用法が実際のプロジェクトで使用されることはほとんどありませんが、上位コンポーネントによってカプセル化された再利用ロジックを、パッケージ化されたコンポーネントのメソッドまたはプロパティによって共同でサポートする必要がある場合に便利です。

3. コンポーネントの状態の改善

上位コンポーネントは、パッケージ化されたコンポーネントの状態と、それに対応する状態処理メソッドを上位コンポーネント自体に昇格させることで、パッケージ化されたコンポーネントのステートレス性を実現できます。典型的なシナリオは、高次コンポーネントを使用して、元々制御されていたコンポーネントが維持する必要がある状態を高次コンポーネントに統合することです。

import React, { Component } from 'react'

function withRef(wrappedComponent) {
  return class extends Component{
    constructor(props) {
      super(props);
      this.state = {
        value: ''
      }
      this.handleValueChange = this.handleValueChange.bind(this);
    }

    handleValueChange(event) {
      this.this.setState({
        value: event.EventTarget.value
      })
    }

    render() {
      // newProps保存受控组件需要使用的属性和事件处理函数
      const newProps = {
        controlledProps: {
          value: this.state.value,
          onChange: this.handleValueChange
        }
      }
      return <wrappedComponent {...this.props} {...newProps}/>
    }
  }
}

この例では、制御コンポーネントの value 属性と、値の変更を処理するコールバック関数によって使用される状態を上位コンポーネントにアップグレードします。制御コンポーネントを再度使用する場合は、次のように使用できます。

import React, { Component } from 'react'

function withControlledState(wrappedComponent) {
  return class extends Component{
    constructor(props) {
      super(props);
      this.state = {
        value: ''
      }
      this.handleValueChange = this.handleValueChange.bind(this);
    }

    handleValueChange(event) {
      this.this.setState({
        value: event.EventTarget.value
      })
    }

    render() {
      // newProps保存受控组件需要使用的属性和事件处理函数
      const newProps = {
        controlledProps: {
          value: this.state.value,
          onChange: this.handleValueChange
        }
      }
      return <wrappedComponent {...this.props} {...newProps}/>
    }
  }
}


class  SimpleControlledComponent extends React.Component {
  render() {
    // 此时的 SimpleControlledComponent 为无状态组件,状态由高阶组件维护
    return <input name="simple" {...this.props.controlledProps}/>
  }
}

const ComponentWithControlledState = withControlledState(SimpleControlledComponent);

3. パラメータの受け渡し

上位コンポーネントのパラメータは 1 つのコンポーネントだけでなく、他のパラメータも受け取ることができます。例えば、最初の例では、LocalStorage からキーデータを持つデータを取得していますが、データを取得するキーが不明な場合、上位コンポーネントの withPersistentData はニーズを満たしません。 LocalStorage からどのデータを取得するかを決定する追加パラメータを受け取ることができます:

import React, { Component } from 'react'

function withPersistentData(WrappedComponent, key) {
  return class extends Component {
    componentWillMount() {
      let data = localStorage.getItem(key);
      this.setState({ data });
    }
    render() {
      // 通过{ ...this.props} 把传递给当前组件属性继续传递给被包装的组件
      return <WrappedComponent data={this.state.data} {...this.props} />
    }
  }
}

class MyComponent extends Component {
  render() {
    return <p>{this.props.data}</p>
  }
}
// 获取 key='data' 的数据
const MyComponent1WithPersistentData = withPersistentData(MyComponent, 'data');

// 获取 key='name' 的数据
const MyComponent2WithPersistentData = withPersistentData(MyComponent, 'name');

withPersistentData の新しいバージョンは、さまざまなキー値を取得するニーズを満たしますが、実際の状況では、このメソッドを使用してデータを渡すことはほとんどありません。パラメータ ですが、より柔軟で使いやすい関数形式が採用されています。

HOC(...params)(WrappedComponent)

HOC(...params) の戻り値は上位コンポーネントです。上位コンポーネントに必要なパラメータは、まずはHOC機能。この形式の withPersistentData を次のように書き換えます (注: この形式の上位コンポーネントはアロー関数を使用してより簡潔に定義されています):

import React, { Component } from 'react'

const withPersistentData = (key) => (WrappedComponent) => {
  return class extends Component {
    componentWillMount() {
      let data = localStorage.getItem(key);
      this.setState({ data });
    }
    render() {
      // 通过{ ...this.props} 把传递给当前组件属性继续传递给被包装的组件
      return <WrappedComponent data={this.state.data} {...this.props} />
    }
  }
}

class MyComponent extends Component {
  render() {
    return <p>{this.props.data}</p>
  }
}
// 获取 key='data' 的数据
const MyComponent1WithPersistentData = withPersistentData('data')(MyComponent);

// 获取 key='name' 的数据
const MyComponent2WithPersistentData = withPersistentData('name')(MyComponent);

4. 継承による上位コンポーネントの実装

As前に紹介した 上位コンポーネントが実装される方法は、上位コンポーネントが共通ロジックを処理し、関連するプロパティをパッケージ化されたコンポーネントに渡すことです。このメソッドをプロパティ プロキシと呼びます。属性プロキシに加えて、上位コンポーネントも継承を通じて実装できます。ロジックの再利用は、パッケージ化されたコンポーネントを継承することによって実現できます。継承を通じて実装された高次コンポーネントは、レンダリングのハイジャックによく使用されます。たとえば、ユーザーがログインしているときはコンポーネントがレンダリングできるようにし、それ以外の場合は空のコンポーネントがレンダリングされるようにします。コードは次のとおりです。

function withAuth(WrappedComponent) {
  return class extends WrappedComponent {
    render() {
      if (this.props.loggedIn) {
        return super.render();
      } else {
        return null;
      }
    }
  }
}

WrappedComponent の this.props.loggedIn に基づいてユーザーがログインしているかどうかを判断します。ログインしている場合は、super.render() を介して WrappedComponent の render メソッドを呼び出してコンポーネントをレンダリングします。それ以外の場合は、継承メソッドを返します。上位コンポーネントの実装は、パッケージ化されたコンポーネントに干渉するため、サブクラス コンポーネントがスーパー経由で親クラス コンポーネントのメソッドを呼び出すことを忘れやすくなります。論理損失に陥っています。したがって、高次コンポーネントを使用する場合は、プロキシを介して実装するようにしてください。

関連提案:

超すごいJavaScript Reactフレームワーク入門チュートリアル_基礎知識

MySQL高可用性コンポーネントのMHAパラメータを詳しく解説

以上がReact の高度なコンポーネントとは何ですか? React の高度なコンポーネントの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。