Mastodonのクライアントアプリを作るうえで最もコアな機能であるタイムラインを作成した。 無限スクロールを実装するためにいろいろと調べたりしたのでまとめておく。
FlatListが優秀
- 完全なクロスプラットフォーム。
- オプションの水平モード。
- 設定可能なビューアビリティ コールバック。
- ヘッダーのサポート。
- フッターのサポート。
- セパレーターのサポート。
- 引っ張って更新します。
- スクロールの読み込み。
- ScrollToIndex のサポート。
- 複数列のサポート。
という多くの機能をサポートしているリストコンポーネント。
今回はタイムラインの無限スクロールを実現したいということで、
- リストを引っ張り更新
- リストのそこについたら再フェッチ
上記2つが実現できればいい。
そしてその2つはFlatList
に標準搭載されている。
リストを引っ張り更新
onRefresh
というProps
が用意されている。
このイベントで最新情報を取得し、useState
を更新すればいい。
リストのそこについたら再フェッチで無限スクロール
onEndReached
という Props
が用意されている。
このイベントで最新情報を取得し、useState
を更新すればいい。
その際スクロールのタイミングで重複のデータがset
されることがあった。
重複チェックをすることで解決した。
またonEndReachedThreshold
というProps
を使った。
onEndReachedThreshold: 0 ~ 1の間の数値でどのくらいの距離でonEndReachedを呼び出すかを決められます。0が一番近くで、1が一番遠いです。
という記事を参照したのだけれど、公式のProps
には明記されていなかった。
機能しているかを確認する必要がある。
##その他、実装した機能
ボトムメニューのタブクリックでFlatListのトップにスクロールする
const flatListRef = useRef<FlatList<Interface>>(null);
レンダリング時にドムを取得しておき、タブクリックで書きイベントを発火させる。
if (flatListRef.current) {
flatListRef.current.scrollToOffset({ animated: true, offset: 0 });
}
スクロールバーを非表示にする
showsVerticalScrollIndicator
というProps
をfalse
にする。
まだ実装していないけど試したい機能
List~~~Componentを活用する
ListEmptyComponent
ListFooterComponent
ListHeaderComponent
特にListFooterComponent
は無限スクロール時の読み込みに使えそうなのでUI改善で使っていきたい。
たぶんこれくらい。
使ったProps
は以下の通り。
ref={flatListRef}
data={timeline}
keyExtractor={(item) => item.id}
onEndReached={onEndReached}
onEndReachedThreshold={1}
onRefresh={onRefresh}
refreshing={refreshing}
extraData={timeline}
showsVerticalScrollIndicator={false}
renderItem={({ item, index }) => {}