Reactベースのコンポーネントのカプセル化の実装手順

Reactベースのコンポーネントのカプセル化の実装手順

序文

多くの友人は、初めてコンポーネントをカプセル化しようとすると、私と同じように多くの問題に遭遇します。たとえば、他の人のコンポーネントには色属性があります。コンポーネントを使用するときは、コンポーネント ドキュメントに記述されている primary などの属性値を渡します。すると、このコンポーネントのフォント カラーは primary に対応する色になります。これはどのように行われるのでしょうか。また、他者によってカプセル化されたコンポーネントクラス名には、独自のプレフィックスが付きます。これはどのように対処しますか? すべての CSS クラス名にプレフィックスを追加する必要がありますか? これは面倒すぎます!

これらの質問について混乱している場合は、この記事を読んでください。

antd のディバイダ コンポーネントを参考にして、React ベースのコンポーネントをカプセル化する方法を説明し、上記の質問のいくつかに答えます。 どうぞじっくりお読みください。

antd はどのようにしてコンポーネントをカプセル化するのでしょうか?

倉庫住所

  • Antd リポジトリ アドレス: https://github.com/ant-design/ant-design
  • ディバイダーコンポーネントは、下の図に対応するディレクトリにあります(ここにコードをコピーします。興味がある場合は、リポジトリをクローンできます)。

ディバイダーコンポーネントのソースコード

antd のソースコードは TypeScript 構文を使用しているため、構文を理解していない学生は時間内に学習する必要があります。

'react' から * を React としてインポートします。
'classnames' から classNames をインポートします。
'../config-provider' から ConfigConsumer、ConfigConsumerProps } をインポートします。

エクスポートインターフェースDividerProps {
    prefixCls?: 文字列;
    タイプ: '水平' | '垂直';
    方向?: '左' | '右' | '中央';
    クラス名?: 文字列;
    子?: React.ReactNode;
    破線?: ブール値;
    スタイル?: React.CSSProperties;
    プレーン?: ブール値;
}

定数ディバイダー: React.FC<DividerProps> = props => (
    <ConfigConsumer>
        {({ getPrefixCls, 方向 }: ConfigConsumerProps) => {
            定数{
                prefixCls: カスタマイズPrefixCls、
                タイプ = '水平'、
                方向 = '中心'、
                クラス名、
                子供たち、
                破線、
                無地、
                ...レストプロップ
            } = プロパティ;
            const prefixCls = getPrefixCls('divider', customizePrefixCls);
            const orientationPrefix = orientation.length > 0 ? `-${orientation}` : 方向;
            const hasChildren = !!children;
            定数classString = classNames(
                プレフィックスCls、
                `${prefixCls}-${type}`、
                {
                    [`${prefixCls}-with-text`]: 子を持つ、
                    [`${prefixCls}-with-text${orientationPrefix}`]: 子を持ちます、
                    [`${prefixCls}-dashed`]: !!dashed,
                    [`${prefixCls}-p​​lain`]: !!プレーン,
                    [`${prefixCls}-rtl`]: 方向 === 'rtl',
                },
                クラス名、
            );
            戻る (
                <div className={classString} {...restProps} 役割="セパレーター">
                    {子供 && <span className={`${prefixCls}-inner-text`}>{子供}</span>}
                </div>
            );
        }}
    </ConfigConsumer>
);

デフォルトのディバイダをエクスポートします。

コンポーネントのプロパティを公開する方法

ソース コードで最初に目にするのは、次の内容です。これらのプロパティは、区切り線コンポーネントによって公開されるプロパティでもあります。 <Divider type='vertical' />のように type 属性を渡すことができるので、区切り線のスタイルは垂直の区切り線としてレンダリングされます。見覚えがありませんか?

export interface DividerProps { // インターフェースは TypeScript 構文です prefixCls?: string;
    type?: 'horizo​​ntal' | 'vertical'; // タイプを 2 つの値のうち 1 つのみに制限します orientation?: 'left' | 'right' | 'center';
    クラス名?: 文字列;
    子?: React.ReactNode;
    破線?: ブール値;
    スタイル?: React.CSSProperties;
    プレーン?: ブール値;
}

上記の属性では、className と style が比較的一般的な属性であることもわかりました。つまり、これらの属性は<Divider type='vertical' className='myClassName' style={{width: '1em'}} />のように使用できます。

統一されたクラス名プレフィックスを設定する方法

antd のコンポーネント クラス名には独自のプレフィックスant-があることはわかっていますが、これはどのように処理されるのでしょうか?引き続きソースコードを見てみましょう。

<ConfigConsumer>
    {({ getPrefixCls, 方向 }: ConfigConsumerProps) => {
        定数{
            prefixCls: カスタマイズPrefixCls、
            タイプ = '水平'、
            方向 = '中心'、
            クラス名、
            子供たち、
            破線、
            無地、
            ...レストプロップ
        } = プロパティ;
        const prefixCls = getPrefixCls('divider', customizePrefixCls);

ソース コードから、getPrefixCls メソッドによって生成された prefixCls を見つけます。次に、getPrefixCls メソッドのソース コードを見てみましょう。

エクスポートインターフェースConfigConsumerProps {
  ...
  getPrefixCls: (suffixCls?: 文字列、customizePrefixCls?: 文字列) => 文字列;
  ...
}

const defaultGetPrefixCls = (suffixCls?: 文字列、customizePrefixCls?: 文字列) => {
  if (customizePrefixCls) は customizePrefixCls を返します。

  suffixCls を返します ? `ant-${suffixCls}` : 'ant';
};

このとき生成されるクラス名プレフィックスがant-dividerであることは簡単にわかります

スタイルとクラス名の扱い方

カプセル化するコンポーネントには、事前に設定されたスタイルが必要です。スタイルはクラス名によって定義され、渡される属性値によってコンポーネントに追加するクラス名が決まるのですが、これはどのように実現されるのでしょうか。以下のソースコードを見てみましょう。

'classnames' から classNames をインポートします。

const クラス文字列 = クラス名(
    プレフィックスCls、
    `${prefixCls}-${type}`、
    {
        [`${prefixCls}-with-text`]: 子を持つ、
        [`${prefixCls}-with-text${orientationPrefix}`]: 子を持ちます、
        [`${prefixCls}-dashed`]: !!dashed,
        [`${prefixCls}-p​​lain`]: !!プレーン,
        [`${prefixCls}-rtl`]: 方向 === 'rtl',
    },
    クラス名、
);
戻る (
    <div className={classString} {...restProps} 役割="セパレーター">
        {子供 && <span className={`${prefixCls}-inner-text`}>{子供}</span>}
    </div>
);

classNames メソッド (classNames は複数のクラス名を処理する React のコンポーネントです) を通じてすべてのクラス名の定数を定義し、それを div 内の className 属性に渡すことがわかりました

実際、生成されたクラス名はant-divider-horizontalなので、このクラス名で CSS に定義されたスタイルが自然に有効になります。 className 属性と style 属性は{...restProps}を介して渡されます。

最後に、CSS スタイルコードがどのように記述されているかを見てみましょう。

ディバイダーコンポーネントスタイルのソースコード

antd コンポーネントのスタイルは Less で記述されています。Less 構文に慣れていない学生は、Less 構文について学ぶ必要があります。

@import '../../style/themes/index';
@import '../../style/mixins/index';

@divider-prefix-cls: ~'@{ant-prefix}-divider'; // これは、前述のクラス名プレフィックスに対応していることがわかります。@{divider-prefix-cls} {
  .reset-component();

  上境界線: @border-width-base solid @divider-color;

  &-vertical { // ここでの完全なクラス名は実際には ant-divider-vertical であり、これは type 属性値が vertical position: relative の場合の区切りコンポーネントに対応するスタイルです。
    上: -0.06em;
    表示: インラインブロック;
    高さ: 0.9em;
    マージン: 0 8px;
    垂直位置合わせ: 中央;
    上境界線: 0;
    左境界線: @border-width-base solid @divider-color;
  }

  &-水平{
    ディスプレイ: フレックス;
    クリア: 両方;
    幅: 100%;
    最小幅: 100%; 
    マージン: 24px 0;
  }

  &-水平&-テキスト付き{
    ディスプレイ: フレックス;
    マージン: 16px 0;
    色: @heading-color;
    フォントの太さ: 500;
    フォントサイズ: @font-size-lg;
    空白: ラップなし;
    テキスト配置: 中央;
    上境界線: 0;
    境界線の上部の色: @divider-color;

    &::前に、
    &::後 {
      位置: 相対的;
      上位: 50%;
      幅: 50%;
      border-top: @border-width-base solid transparent;
      // Chrome は `border-top` 内の `inherit` を受け入れません
      境界線上部の色: 継承;
      下境界線: 0;
      変換: translateY(50%);
      コンテンツ: '';
    }
  }

  &-horizo​​ntal&-with-text-left {
    &::前に {
      上位: 50%;
      幅: @divider-orientation-margin;
    }

    &::後 {
      上位: 50%;
      幅: 100% - @divider-orientation-margin;
    }
  }

  &-horizo​​ntal&-with-text-right {
    &::前に {
      上位: 50%;
      幅: 100% - @divider-orientation-margin;
    }

    &::後 {
      上位: 50%;
      幅: @divider-orientation-margin;
    }
  }

  &-内部テキスト{
    表示: インラインブロック;
    パディング: 0 @divider-text-padding;
  }

  &-破線 {
    背景: なし;
    境界線の色: @divider-color;
    境界線スタイル: 破線;
    境界線の幅: @border-width-base 0 0;
  }

  &-水平&-テキスト付き&-破線 {
    上境界線: 0;

    &::前に、
    &::後 {
      境界線スタイル: 破線 なし なし;
    }
  }

  &-垂直&-破線 {
    境界線の幅: 0 0 0 @境界線の幅のベース;
  }

  &プレーン&テキスト付き{
    色: @テキストカラー;
    フォントの太さ: 標準;
    フォントサイズ: @font-size-base;
  }
}

@import './rtl';

このように、コンポーネントをカプセル化する方法やポイントについても、大まかな理解は得られたと思います。ここでの ConfigConsumer の定義や使い方など、ソースコードには学ぶ価値のある箇所がまだまだたくさんあります。興味のある学生同士、ぜひコミュニケーションをとってみてください。

Reactベースのカプセル化コンポーネントの実装手順についてはこれで終了です。Reactカプセル化コンポーネントの関連コンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 最も単純な ErrorBoundary コンポーネントをカプセル化して、React 例外を処理する
  • React Form コンポーネント実装のカプセル化
  • React チュートリアル: Portal の再利用可能なコンポーネントをカプセル化する方法
  • React Native 通知メッセージの垂直カルーセル コンポーネントのカプセル化
  • React に基づいてコンポーネントをカプセル化する方法を知っていますか?

<<:  SQL 挿入文の書き方の説明

>>:  Docker で nginx のログレベルを調整する方法

推薦する

Tomcat サーバーの設定と Web プロジェクトの公開に関する IDEA グラフィック チュートリアル

1. Webプロジェクトを作成したら、Tomcatを例にサーバーを構成する必要があります。 2. 実...

アクセス速度を上げるためにウェブサイトを最適化する方法の更新

最近、同社はitpubを皮切りに、コーポレートウェブサイト傘下の全サイトの評価を開始した。そのために...

MySQL の文字セット utf8 を utf8mb4 に変更する方法

MySQL 5.5 の場合、文字セットが設定されていない場合、MySQL のデフォルトの文字セットは...

Bootstrap 3.0 の特殊効果の学習ノート(表示と非表示、フローティングの除去、閉じるボタンなど)

この記事の主な内容は次のとおりです。 1. 閉じるボタン2.キャレット3. フローティングを素早く設...

Linux の MariaDB データベースについて

目次Linux の MariaDB データベースについて1. データベースとは何ですか? 2. デー...

IDEA の Maven プロジェクトで MySQL 8.0 に接続して使用する方法に関するチュートリアル

まず、私の基本的な開発環境を見てみましょう。オペレーティングシステム: MacOS 10.13.5 ...

three.js で 3D ダイナミック テキスト効果を実現する方法

序文みなさんこんにちは。CSS ウィザードの alphardex です。以前、海外のウェブサイトを閲...

Webページ作成の質問: 画像ファイルのパス

この記事は 123WORDPRESS.COM Lightning によるオリジナルです。転載する際に...

mysql 簡単な操作例を表示

この記事では、例を挙げて mysql show 操作について説明します。ご参考までに、詳細は以下の通...

Linux ファイルを分割するための split コマンドの詳細な説明

いくつかの簡単な Linux コマンドを使用すると、ストレージまたは電子メールの添付ファイルのサイズ...

WeChatアプレットのオーディオコンポーネントがiOSで再生できない問題の解決策

解決策:クリック イベントをオーディオ コンポーネントにバインドし、再生メソッドと一時停止メソッドを...

mysqlサーバーは--skip-grant-tablesオプションで実行されています

MySQLサーバーは--skip-grant-tablesオプションで実行されているため、このステー...

HTMLのフォントがline-heightを指定しても垂直方向に中央揃えできない問題の解決方法を詳しく説明します

による写真に示されている効果を例に挙げてみましょう。明らかに、「次へ」というテキストを水平方向だけで...

Nginx Rewrite の使用シナリオと設定方法の分析

Nginx Rewriteの使用シナリオ1. URL アドレスジャンプ。たとえば、ユーザーが pm....

Angularコンポーネントライフサイクルの詳細説明(I)

目次概要1. フックの呼び出し順序2. onChangesフック3. 変更検出メカニズムとDoChe...