👀

FlatList のアイテムをユーザーが見たときに一度だけ何かする

2024/02/04に公開

よくあるのは Google Analytics など、行動ログを記録したい場合だろうか。

FlatList オプション

FlatList にはこうした場合に使えるオプションが用意されている。

オプションをどう指定したらどうなるかは次が詳しい。

https://zenn.dev/luvmini511/articles/b28c0383b5d28a

また、「見た」かどうかの条件を複数持たせたい場合は viewabilityConfigCallbackPairs というオプションを使う。 Pairs という名の通り viewabilityConfigonViewableItemsChanged のペアを 1 セットとして扱う。

<FlatList
  onViewableItemsChanged={[
    {
      viewabilityConfig: {
        itemVisiblePercentThreshold: 50,
        minimumViewTime: 2000,
      },
      onViewableItemsChanged: () => {
        console.log("半分が 2 秒以上表示されているときに「見た」とする");
      },
    },
    {
      viewabilityConfig: {
        viewAreaCoveragePercentThreshold: 0,
        minimumViewTime: 0,
        waitForInteraction: true,
      },
      onViewableItemsChanged: () => {
        console.log(
          "ユーザーの表示後、 1px でも表示されたら即座に「見た」とする"
        );
      },
    },
  ]}
/>

「一度だけ」の判定

「見た」ときに記録することで対応する。その際レンダリングが走らないように ref を使う。

custom hook として定義するとこんな感じ。

https://github.com/januswel/ViewabilityConfigSample/blob/main/useOnViewedItem.ts

Array#push を使って複数の条件を指定できるように onViewableItemsChanged に渡せる形で結果を返している。

`ViewToken` 型の改良

ViewToken のプロパティ item の型が any なので使いづらい。これを何とかするために ViewToken を generic な型として定義しなおして使っている。

import type { ViewToken as RNViewToken } from "react-native";

export type ViewToken<$Item> = Omit<RNViewToken, "item"> & { item: $Item };

使うときは次のようにする。

export default function App(): React.JSX.Element {
  const onViewConfigurations = useOnViewedItem<Item>((token) => {
    console.log("viewed", token);
  });

  return <FlatList viewabilityConfigCallbackPairs={onViewConfigurations} />;
}
GitHubで編集を提案

Discussion