react-virtualized を使用して、動的な高さを持つ画像の長いリストを実装する

react-virtualized を使用して、動的な高さを持つ画像の長いリストを実装する

バーチャルリストは、スクロールコンテナ要素の表示領域に応じて、データの一部を長いリストとしてレンダリングする技術です。仮想リストは、長いリストのシナリオでよく使用される最適化です。結局のところ、リストに何百ものサブ要素をレンダリングする人はほとんどいません。スクロール バーが水平または垂直にスクロールするときに、表示領域に要素をレンダリングするだけで十分です。

開発中に発生した問題

1. 長いリスト内の画像は、元の写真と同じ比率を維持する必要があります。垂直スクロール時に幅が変化しない場合、各画像の高さは動的になります。リスト項目の高さが変化すると、リスト項目と後続のすべてのリスト項目の位置情報に影響します。

2. 画像の幅と高さは、画像が読み込まれた後にのみ取得できます。

解決

react-virtualizedのリストコンポーネントを使用します。公式の例です。

'react' から React をインポートします。
'react-dom' から ReactDOM をインポートします。
'react-virtualized' から {List} をインポートします。

// データを文字列の配列としてリストします
定数リスト = [
  「ブライアン・ヴォーン」
  // 等々...
];

関数 rowRenderer({
  key, // 行の配列内の一意のキー
  index, // コレクション内の行のインデックス
  isScrolling, // リストは現在スクロール中です
  isVisible, // この行はリスト内に表示されます (つまり、オーバースキャンされた行ではありません)
  style, // 行に適用されるスタイル オブジェクト (配置するため)
}) {
  戻る (
    <div キー = {キー} スタイル = {スタイル}>
      {リスト[インデックス]}
    </div>
  );
}

// リストをレンダリングする
ReactDOM.render() は、
  <リスト
    幅={300}
    高さ={300}
    rowCount={リストの長さ}
    行の高さ={20}
    行レンダラー = {行レンダラー}
  />,
  document.getElementById('例')、
); 

rowHeight は各行の高さです。固定の高さまたは関数を渡すことができます。子要素の高さが変わるたびに、インデックスを指定した後、行の高さとオフセットを再計算するために recomputeRowHeights メソッドを呼び出す必要があります。

具体的な実装

const ImgHeightComponent = ({ imgUrl, onHeightReady, 高さ, 幅 }) => {
  const [スタイル、setStyle] = useState({
    身長、
    幅、
    表示: 'ブロック'、
  })
  const getImgWithAndHeight = (url) => {
    新しい Promise を返します ((resolve, reject) => {
      var img = 新しい画像()
      // 画像のsrcを変更する
      img.src = URL
      set = null とする
      定数onload = () => {
        if (画像の幅 || 画像の高さ) {
          //画像の読み込みが完了しました clearInterval(set)
          解決({ 幅: img.width, 高さ: img.height })
        }
      }
      設定 = setInterval(onload, 40)
    })
  }

  使用効果(() => {
    getImgWithAndHeight(imgUrl).then((サイズ) => {
      定数 currentHeight = size.height * (幅 / size.width)
      スタイルを設定する({
        高さ: 現在の高さ、
        幅: 幅、
        表示: 'ブロック'、
      })
      onHeightReady(現在の高さ)
    })
  }, [])
  <img src={imgUrl} alt='' style={style} /> を返します
}

まず、画像の高さを取得するコンポーネントを記述し、タイムループ検出を通じて高さを取得して計算し、それを親コンポーネントに渡します。

'react' から React、{useState、useEffect、useRef} をインポートします。
'./index.scss' からスタイルをインポートします
'react-virtualized/dist/commonjs/AutoSizer' から { AutoSizer } をインポートします。
'react-virtualized/dist/commonjs/List' から {List} をインポートします。

デフォルトのクラスDocumentStudyをエクスポートし、React.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具)
    この状態 = {
      リスト: [], 
      高さ: [],
      自動幅:900、
      自動高さ: 300
    }
  }

  handleHeightReady = (高さ, インデックス) => {
    this.setState() は、
      (状態) => {
        const flag = state.heights.some((item) => item.index === index)
        if (!フラグ) {
          戻る {
            高さ: [
              ...州の高さ、
              {
                索引、
                身長、
              },
            ]、
          }
        }
        戻る {
          高さ: state.heights、
        }
      },
      () => {
        this.listRef.recomputeRowHeights(インデックス)
      },
    )
  }

  getRowHeight = ({ インデックス }) => {
    定数 row = this.state.heights.find((item) => item.index === インデックス)
    行を返します? row.height: this.state.autoHeight
  }

  renderItem = ({ インデックス、キー、スタイル }) => {
    const { リスト、自動幅、自動高さ } = this.state
    if (this.state.heights.find((item) => item.index === index)) {
      戻る (
        <div キー = {キー} スタイル = {スタイル}>
          <img src={list[index].imgUrl} alt='' style={{width: '100%'}}/>
        </div>
      )
    }

    戻る (
      <div キー = {キー} スタイル = {スタイル}>
        <画像高さコンポーネント
          imgUrl={リスト[インデックス].imgUrl}
          幅={自動幅}
          高さ={自動高さ}
          onHeightReady={(高さ) => {
            this.handleHeightReady(高さ、インデックス)
          }}
        />
      </div>
    )
  }

  与える() {
    const { リスト } = this.state
    戻る (
      <>
        <div スタイル = {{ 高さ: 1000 }}>
          <オートサイザー>
            {({ 幅, 高さ }) => (
              <リスト
                ref={(ref) => (this.listRef = ref)}
                幅={幅}
                高さ={高さ}
                オーバースキャン行数={10}
                rowCount={リストの長さ}
                rowRenderer={this.renderItem}
                行の高さ={this.getRowHeight}
              />
            )}
          </オートサイザー>
        </div>
      </>
    )
  }
}

親コンポーネントは、handleHeightReady メソッドを通じてすべての画像の高さを収集し、高さが変化するたびに List コンポーネントの recomputeRowHeights メソッドを呼び出して、コンポーネントに高さとオフセットを再計算するように通知します。この時点で、遭遇した問題は基本的に解決されました。

実績

まとめ

現在、長い画像リストを実装するために react-virtualized のみを使用しています。 react-virtualized の具体的な内部実装については、さらに調査する必要があります。

上記は react-virtualized を使用して動的な画像の長いリストを実装する詳細です。 react virtualized の長いリストの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • React Native での ScrollView コンポーネント カルーセルと ListView レンダリング リスト コンポーネントの使用例の分析
  • Reactモバイル端末は左にスワイプしてリストを削除するサンプルコードを実装します
  • React Native カスタム プルダウン リフレッシュ プルアップ ロード済みリストの例
  • React Native インデックス付き都市リスト コンポーネントのサンプル コード
  • Reactはクリックするとリスト内の対応する項目が削除されるように実装します

<<:  CentOS に PHP5 をインストール、PHP をアンインストール、PHP7 をインストールするチュートリアル

>>:  MySQL Innodbインデックスの原理の詳細な説明

推薦する

Mysql 複数データベースのバックアップ コード例

この記事は主にMysqlの複数データベースのバックアップのコード例を紹介します。この記事ではサンプル...

ブラインドの特殊効果を実現するネイティブJS

この記事では、ネイティブ JS で実装されたブラインドの特殊効果を紹介します。効果は次のとおりです。...

Dockerコンテナの紹介

1. 概要1.1 基本概念: Docker は、Go 言語をベースにしたオープンソースのアプリケーシ...

MySqlデータベースをバックアップするいくつかの方法

mysqldump ツールのバックアップデータベース全体をバックアップする $> mysqld...

MySQL 5.7.20 のインストールと設定方法のグラフィック チュートリアル (win10)

この記事では、MySQL 5.7.20のインストールと設定方法を参考までに紹介します。具体的な内容は...

Doubanウェブサイトのウェブサイトコンテンツに小さな変更を加える方法

<br />読みやすさはウェブサイトにとって非常に重要な部分であり、ウェブサイトの核心と...

Nginx の http リソース リクエスト制限の詳細な説明 (3 つの方法)

前提条件: nginx には、ngx_http_limit_conn_module モジュールと n...

要素の読み込み効果を実現するための純粋なHTML+CSS

これは Element UI の読み込みコンポーネントのエフェクトです。かっこいいですね。実装してみ...

MySQL のロードバランサーとして nginx を使用する方法

注意: nginxのバージョンは1.9以上である必要があります。nginxをコンパイルするときに、-...

CSSトランジションは高さを変更することで要素を拡大したり縮小したりします。

一般的な開発ニーズとして、要素の一部を必要になるまで折りたたんでおきたいことが挙げられます。 Boo...

自動同期テーブル構造のMySql開発

開発の問題点開発プロセスでは、データベース フィールドが頻繁に変更されるため、RD 環境と QA 環...

binlog2sql と簡単なバックアップおよびリカバリを使用して mysql8.0.20 を構成するための詳細な手順

目次最初のステップのインストールステップ2: MySQLデータを準備する3 番目のステップは、bin...

Linuxでブーストライブラリをインストールするための完全な手順

序文Boost ライブラリは、標準ライブラリのバックアップとして機能し、C++ 標準化プロセスの開発...

AngularでTweenMaxアニメーションライブラリを使用する際の問題と解決策

最近何もすることがないのでCSSをいじっていますより良いアニメーションライブラリTweenMaxを見...

JavaScript 関数の高度な説明

目次関数定義方法関数呼び出し(6種類)これは問題を指摘している厳密モード高階関数閉鎖再帰: 自分自身...