🧢
無限スクロールにはReact-Virtuosoが良さそう🧩
結論
タイトルにもありますが無限スクロールの 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)で次の問題が発生した。
- 1 ページに描画できるデータ数が 99 件(react-data-grid/pagination/#size-of-the-page)のため無限スクロールに対応が出来ない。
- free plan では無限スクロールの関数(infinite loading - onRowsScrollEnd)の使用を許可されていない
- グリッド(マトリクス)ビューで結局無限スクロールの実装が必要になる
DataGrid Pro にアップグレードするか、それ以外か
まず、100 件以上にデータ表示対応するためには、以下 2 つのどちらかを採用するか検討する必要がある。
- DataGrid を ProPlan にアップグレードする
- DataGrid を廃止し、無限スクロールライブラリを活用しテーブルをリプレースする。
この 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