🧢
無限スクロールには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