目次
1.1 パラメータを渡してクラスを変更する
1.2 クラスの属性を変更する
4.4 组合多个高阶组件
6.2 React Sortable
ホームページ ウェブフロントエンド jsチュートリアル es7のデコレータを詳しく解説(例付き)

es7のデコレータを詳しく解説(例付き)

Oct 26, 2018 pm 03:32 PM
es6 javascript react.js

この記事では、es7 の Decorator について詳しく説明します (例を示します)。必要な方は参考にしていただければ幸いです。

1. Decorator の基礎知識

多くのフレームワークやライブラリ、特に React、Redux、mobx で見られます。

Decorator は、クラスの動作を変更するために使用される関数です。この抽象的な概念はよく理解できないので、コードを見てより実践的に説明することをお勧めします。

//定义一个函数,也就是定义一个Decorator,target参数就是传进来的Class。
//这里是为类添加了一个静态属性
function addAge(target) {
  target.age = 2;
}

//在Decorator后面跟着Class,Decorator是函数的话,怎么不是addAge(MyGeekjcProject)这样写呢?
//我只能这样理解:因为语法就这样,只要Decorator后面是Class,默认就已经把Class当成参数隐形传进Decorator了(就是所谓的语法糖)。
@addAge
class MyGeekjcProject {}

console.log(MyGeekjcProject.age) // 2
ログイン後にコピー

1.1 パラメータを渡してクラスを変更する

しかし、上記のメソッドが 1 つのクラスのみをパラメータとして渡し、十分な柔軟性がない場合はどうすればよいでしょうか。
最終結果が Decorator である限り、外側の層に関数を設定できます。設定する関数の数や渡すパラメーターの数は関係ありません。

function addAge(age) {
  return function(target) {
    target.age = age;
  }
}

//注意这里,隐形传入了Class,语法类似于addAge(2)(MyGeekjcProject)
@testable(2)
class MyGeekjcProject {}
MyGeekjcProject.age // 2

@addAge(3)
class MyGeekjcProject {}
MyGeekjcProject.age // 3
ログイン後にコピー

1.2 クラスの属性を変更する

以下は変更されたクラスのプロトタイプ オブジェクトです

function description(target) {
  target.prototype.url = 'https://www.geekjc.com';
}

@description
class MyGeekjcProject {}

let geekjc = new MyGeekjcProject();
geekjc.url // https://www.geekjc.com
ログイン後にコピー

修飾子はクラスを変更できるという概念は大まかに理解できます。

//假如修饰类的属性则传入三个参数,对应Object.defineProperty()里三个参数,具体不细说
//target为目标对象,对应为Class的实例
//name为所要修饰的属性名,这里就是修饰器紧跟其后的name属性
//descriptor为该属性的描述对象
//这里的Decorator作用是使name属性不可写,并返回修改后的descriptor
function readonly(target, name, descriptor){
  descriptor.writable = false;
  return descriptor;
}

class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}
ログイン後にコピー

Object.defineProperty() については、記事を読んで Object.defineProperty を学習してください。

もう一度複雑な例を見てみましょう。

//定义一个Class并在其add上使用了修饰器
class Math {
  @log
  add(a, b) {
    return a + b;
  }
}

//定义一个修饰器
function log(target, name, descriptor) {
  //这里是缓存旧的方法,也就是上面那个add()原始方法
  var oldValue = descriptor.value;

  //这里修改了方法,使其作用变成一个打印函数
  //最后依旧返回旧的方法,真是巧妙
  descriptor.value = function() {
    console.log(`Calling "${name}" with`, arguments);
    return oldValue.apply(null, arguments);
  };

  return descriptor;
}

const math = new Math();
math.add(2, 4);
ログイン後にコピー
上記のコードを読むと、デコレータが何に使用されるかがわかります。はい、修飾子はクラスの動作を変更するだけでなく、クラスの属性も変更できます。

2. React の高次コンポーネント

より一般的には、高次コンポーネントは、React コンポーネントをラップ (ラップ) することによって渡され、一連の最後に、他のコンポーネントを呼び出すために比較的強化された React コンポーネントが返されます。

3. 上位コンポーネントを実装する

React コンポーネントを受け取り、それをラップして を返す、最も単純な上位コンポーネント (関数) を実装しましょう。

export default function withDescription(WrappedComponent) {
  return class HOC extends Component {
    render() {
      return <div>
        <div>
          极客教程(https://www.geekjc.com)致力于推广各种编程语言技术,也为了未来数字化世界,让人更容易找到操作数字化的方式,为了未来而生的编程学习平台,
          大部分资源是完全免费的,并且会根据当前互联网的变化实时更新本站内容。
        </div>
        <wrappedcomponent></wrappedcomponent>
      </div>
    }
  }
}
ログイン後にコピー
他のコンポーネントでは、この上位コンポーネントを参照して強化します。

@withDescription
export default class Geekjc extends Component {
  render() {
    return (
      <div>
        我是一个普通组件
      </div>
    );
  }
}
ログイン後にコピー
ここでは、書き方の優雅さを向上させるために ES7 のデコレータを使用しています (最初のセクションのデコレータを参照) が、実際には単なる構文上の糖衣です。次のような書き方も可能です。

const EnhanceDemo = withDescription(Geekjc);
ログイン後にコピー
次に、React コンポーネント ツリーでどのような変更が行われたかを観察します。図に示すように、Geekjc コンポーネントが HOC コンポーネントによってラップされていることがわかります。これは、高い期待と一致しています。 -order コンポーネント。つまり、コンポーネントはタマネギのようにレイヤーごとにラップされます。

es7のデコレータを詳しく解説(例付き)

しかし、それに伴う問題は、この上位コンポーネントが複数回使用されると、デバッグ時に次のように表示されることです。

HOC が大量にあるため、この時点で少し最適化を行う必要があります。つまり、上位コンポーネントがラップされた後、元の名前を保持する必要があります。

上記の上位コンポーネントのコードを書き換えて、

getDisplayName 関数と静的属性 displayName を追加して、 DOM Tree を観察します。

function getDisplayName(component) {
  return component.displayName || component.name || 'Component';
}
export default function (WrappedComponent) {
  return class HOC extends Component {
    static displayName = `HOC(${getDisplayName(WrappedComponent)})`
    render() {
      return <div>
        <div>
          极客教程(https://www.geekjc.com)致力于推广各种编程语言技术,也为了未来数字化世界,让人更容易找到操作数字化的方式,为了未来而生的编程学习平台,
          大部分资源是完全免费的,并且会根据当前互联网的变化实时更新本站内容。
        </div>
        <wrappedcomponent></wrappedcomponent>
      </div>
    }
  }
}
ログイン後にコピー

es7のデコレータを詳しく解説(例付き)

現時点では、元のコンポーネントの名前が DOM ツリーに正しく表示されます。

この単純な例では、上位コンポーネントはラップされたコンポーネントに

タイトル スタイル を追加するという 1 つのことだけを行います。この上位コンポーネントは、このロジックを追加する必要がある任意のコンポーネントで使用でき、この上位コンポーネントによってのみ変更する必要があります。

上位コンポーネントの主な機能は、コンポーネントの共通ロジックをカプセル化して抽象化し、ロジックのこの部分をコンポーネント間でより適切に再利用できるようにすることであることがわかります。

4. 上位コンポーネントの高度な使用法

4.1 コンポーネントのパラメーター

上記の例を例に挙げますが、この上位コンポーネントは情報のみを表示します。 Web サイトの説明についてですが、より適切に抽象化するには、この説明をパラメータ化して次のように呼び出す必要があります。

@withDescription('欢迎大家访问收藏(https://www.geekjc.com)') 
export default class Geekjc extends Component {
  render() {
    return (
      //...
    );
  }
}
ログイン後にコピー
withDescription は、パラメータを受け取り、上位のコンポーネント (関数) を返す次の形式に書き換える必要があります。

export default function (description) {
  return function (WrappedComponent) {
    return class HOC extends Component {
      render() {
        return <div>
          <div>
            {description
              ?description
              : '我是描述'}
          </div>
          <wrappedcomponent></wrappedcomponent>
        </div>
      }
    }
  }
}
ログイン後にコピー
ES6 を使用すると、より簡潔に記述できます。

export default(description) => (WrappedComponent) => class HOC extends Component {
  render() {
    return <div>
      <div>
        {description
          ? description
          : '我是描述'}
      </div>
      <wrappedcomponent></wrappedcomponent>
    </div>
  }
}
ログイン後にコピー
図からわかるように、渡されたパラメータが DOM ツリーに反映されています。

es7のデコレータを詳しく解説(例付き)

カリー化カリー

コンセプト: 関数のパラメータの一部だけを渡して呼び出し、残りのパラメータを処理する関数を返します。
関数シグネチャ: fun(params)(otherParams)
アプリケーション: React では、カリー化を通じて、さまざまなパラメーターを渡すことでさまざまな高次コンポーネントを取得できます。

4.2 属性プロキシに基づく方法

属性プロキシは、上位コンポーネントを使用する最も一般的な方法です。上で説明した上位コンポーネントはこの方法です。これは、ラップされたコンポーネントのプロパティと新しく生成されたプロパティをこのコンポーネントに渡すためにいくつかの操作を実行します。これはプロパティ プロキシと呼ばれます。

export default function withHeader(WrappedComponent) {
  return class HOC extends Component {
    render() {
      const newProps = {
        test:'hoc'
      }
      // 透传props,并且传递新的newProps
      return <p>
        <wrappedcomponent></wrappedcomponent>
      </p>
    }
  }
}
ログイン後にコピー
4.3 逆継承に基づく

この方法で返された React コンポーネントは、渡されたコンポーネントを継承するため、属性よりも多くの領域と権限にアクセスできます。組織化と変更。詳細については、付録にあるリンクを参照して詳しく学習してください。

export default function (WrappedComponent) {
  return class Inheritance extends WrappedComponent {
    componentDidMount() {
      // 可以方便地得到state,做一些更深入的修改。
      console.log(this.state);
    }
    render() {
      return super.render();
    }
  }
}
ログイン後にコピー

4.4 组合多个高阶组件

上述高阶组件为React组件增强了一个功能,如果需要同时增加多个功能需要怎么做?这种场景非常常见,例如我既需要增加一个组件标题,又需要在此组件未加载完成时显示Loading。

@withDescription
@withLoading
class Demo extends Component{

}
ログイン後にコピー

使用compose可以简化上述过程,也能体现函数式编程的思想。

const enhance = compose(withHeader,withLoading);
@enhance
class Demo extends Component{

}
ログイン後にコピー
组合 Compose
compose可以帮助我们组合任意个(包括0个)高阶函数,例如compose(a,b,c)返回一个新的函数d,函数d依然接受一个函数作为入参,只不过在内部会依次调用c,b,a,从表现层对使用者保持透明。
基于这个特性,我们便可以非常便捷地为某个组件增强或减弱其特征,只需要去变更compose函数里的参数个数便可。

compose函数实现方式有很多种,这里推荐其中一个recompact.compose,详情见下方参考类库,也可以看我之前写的一篇文章reduce与redux中compose函数

5. 与父组件区别

高阶组件作为一个函数,它可以更加纯粹地关注业务逻辑层面的代码,比如数据处理,数据校验,发送请求等,可以改善目前代码里业务逻辑和UI逻辑混杂在一起的现状。父组件则是UI层的东西,我们先前经常把一些业务逻辑处理放在父组件里,这样会造成父组件混乱的情况。为了代码进一步解耦,可以考虑使用高阶组件这种模式。

6. 开源的高阶组件使用

6.1 recompact

recompact提供了一系列使用的高阶组件,可以增强组件的行为,可以利用此库学习高阶组件的写法。

import recompact from 'recompact'
import { pure, withProps } from 'recompact'

const enhance = recompact.compose(
  withProps({ className: 'beautiful' }),
  pure,
)
@enhance
class Demo extends Component{

}
ログイン後にコピー

6.2 React Sortable

通过使用此库提供的高阶组件,可以方便地让列表元素可拖动。

以上がes7のデコレータを詳しく解説(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

See all articles