🧢

無限スクロールにはReact-Virtuosoが良さそう🧩

2023/04/19に公開

結論

タイトルにもありますが無限スクロールのUI実装にはreact-virtuosoが良さそう

経緯

テーブルとグリッドを切り替える事ができる一覧ビューのUIをページネーションから無限スクロールに変更する必要があった。またUI実装は基本的にMUIを活用することが前提です。

  • ページネーション(現状のUI)

    • Datagrid(free plan)とPaginationを使いテーブルのUIを実装(この記事ではDataGridの詳細については言及しません)
    • 1ページ(1テーブル)に20件ずつ表示
    • muiのdatagridサンプルのFooterがbasic-paginationに置き換わるイメージ
  • 無限スクロール(変更後のUI)

    • 1テーブル(1ページ)に対してテーブルの最下部のスクロール毎に20件ずつアイテムが増加する

現在テーブルに使用しているコンポーネント(Datagrid-free plan)で次の問題が発生した。

DataGrid Proにアップグレードするか、それ以外か

まず、100件以上にデータ表示対応するためには、以下2つのどちらかを採用するか検討する必要がある。

この2つの案で発生しそうな作業と懸念点をざっと書いてみる。

1.DataGridをProPlanにアップグレードする

  • free → Proの移行対応
  • infinite-loadingを活用して無限スクロールの実装
  • APIレスポンスの現在表示されているデータにマージする
    • apiリクエストするパラメータの調整
    • 状態管理
  • グリッドビューで結局無限スクロール対応が必要になる
  • MUI Pro Planは1年間で1デベロッパーにつき$180の支払いが必要

2.DataGridを廃止し、無限スクロールライブラリを活用しテーブルをリプレースする

  • DataGridからBasic-Tableにリプレース
  • ローディング
  • 無限スクロールライブラリとリプレースされたMUIのTableコンポーネントを繋ぎ合わせる
    • 要素の最下部にスクロールしたかどうかを返す
    • パフォーマンス最適化
      • スクロール毎にイベントを発火させない(遅延処理)
    • 新しくデータを読み込んだ場合のスクロール位置の調整
      • ローディング表示も必要
    • ページの状態を保持する
      • 一覧から詳細画面に行き、一覧に戻った時に直前の位置を取得する
  • 無限スクロールライブラリの活用でグリッドビューの対応も出来る
  • APIレスポンスの現在表示されているデータにマージする(1と同様)
    • apiリクエストするパラメータの調整
    • 状態管理

1について

  • テーブルの無限スクロール対応は容易
  • テーブルの無限スクロールのためだけに1developerにつき$180払う必要がある
  • グリッドビューで無限スクロールの実装がどちらにしろ必要になりそう

2について

  • テーブル、グリッドビューどちらも同様の手順で対応出来そう(共通化できそう)
  • テーブルのリプレースに時間がかかる

結果、無限スクロールのためだけに課金する必要がないと判断したのと、グリッドビューで無限スクロールの判定を実装することが必要なので、DataGrid Proにアップデートするのはやめました。

無限スクロールライブラリ比較

次にどの無限スクロールライブラリを活用するかの比較を行う。
10 Best React Infinite Scroll Libraries in 2023から3つピックアップして比較してみた。

選んだ基準は以下3点です

  • 1年以内にメンテされている
  • MUIとの相性が良さそうか
  • 無限スクロールのサンプルが用意されている
name 無限スクロール例 備考
react-virtualized https://bvaughn.github.io/react-virtualized/#/components/InfiniteLoader - muiで使用しているテーブルをvirtualizedからvirtuosoに移行にした模様なので少し古そう
- sample実装ではclassコンポーネントで記述されているため少し読みづらい
react-virtuoso https://virtuoso.dev/endless-scrolling/ - endReached(最下部判定)やinitialTopMostItemIndex(初期表示のスクロール位置指定)などの便利そうなプロパティが用意されている
- typescript with hooksで書かれている
TanStack Table https://tanstack.com/table/v8/docs/examples/react/virtualized-infinite-scrolling - 無限スクロールを自前で実装する必要がある
- (例はあるがよく見るとvirtuosoのendReachedのようなものが用意されていなかった)

終わりに

  • そもそも最初に無限スクロールに置き換わるかもしれないことを考慮できていればUIをまるごとリプレースせずに済んだ
  • ブラウザバックした場合のページネーションの状態管理やスクロールの位置管理など他にも記事書けそう
  • 実際にreact-virtuosoを使ってみての感想や使い勝手の良さを後に書こうと思います

Discussion