2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

react-infinite-scrollerを使って無限スクロールを実装する

Posted at

#はじめに
Reactでチャットアプリを作成する際に無限スクロール欲しいよなあと思い作成したので記録しておく。

#仕様
https://github.com/danbovey/react-infinite-scroller

使用するコンポーネントはInfiniteSchrollerのみ。スクロールイベントで発火する仕組みのよう。主にpropsとして使用するものを紹介する。

###loadmore
ロードする際に実行する関数。

###hasMore
loadMoreを実行するかどうかを判断するboolean。のはずなのだが、falseにしてもloadmoreが一回だけ動いたりした。要検証。

###initialLoad
初回にロードするかどうかを決めるboolean。初回時と読み込み時で処理が違う場合はfalseにした方が良さそう。

###loader
ローディング中のUI。

###threshold
スクロールイベントを検知するためのスクロールバーとウィンドウ下の距離。大きくしたり小さくしたりするとエラーが出ることがあるのでテスト必須。

#コード

export const FirebaseChatDisplayArea = () => {
  const { chatData } = useChatDataSelector();
  const { hasMore } = useHasMoreSelector();
  const { isChatsCompleted } = useIsChatsCompletedSelector();
  const { lastChatOrder } = useLastChatOrderSelector();
  const { dispatch } = useAppDispatch();

  //初回時のみ実行、それ以降はDBに変更があった時のみ動作
  useFetchData();

  console.log("チャット表示領域のレンダリング");

  return (
    <SChatListContainer>
      {isChatsCompleted ? (
        <InfiniteScroll
          loadMore={() =>
            loadMore({
              dispatch,
              chatData,
              lastChatOrder,
              hasMore,
            })
          }
          hasMore={hasMore}
          loader={<CircularProgress key={0} />}
          initialLoad={false}
          threshold={50}
        >
          {chatData.length === 0 ? (
            <div>チャットはありません</div>
          ) : (
            chatData.map((item) => {
              return (
                <SChatContainer key={item.key}>
                  <SContent>{item.user_name}</SContent>
                  <SContent>{item.text}</SContent>
                  <SContent>{moment(item.createdAt).fromNow()}</SContent>
                  <SContent>{item.order}</SContent>
                </SChatContainer>
              );
            })
          )}
        </InfiniteScroll>
      ) : (
        <CircularProgress />
      )}
    </SChatListContainer>
  );
};

特に変わったところはないと思います。

#遭遇したエラーと対策
###keyを設定しろと言われる
公式のコードや、issueにも載っているが、loaderにkey={0}としないと怒られる。

###同じデータを読んでしまい、同じkeyが存在すると言われる
thresholdの値が大きすぎるとloadmoreの実行中にもう一度イベントが発生し、同じデータを読んでしまうことがある。このエラーはロジック上の問題であるときもあるので十分な分析が必要。

#おわりに
意外とめんどくさかった。みんな手動で実装してるんだろうか。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?