ReactJS - カスタムフック:無限スクロールのマスター

こんにちは、React開発者を目指している皆さん!今日は、カスタムフックの世界に足を踏み入れ、特に無限スクロール機能の実装に焦点を当てた興奮人心的な旅に出ます。あなたの近所の親切なコンピュータサイエンスの先生として、私はこのプロセスをステップバイステップでガイドし、すべての概念を理解するまでサポートします。では、お気に入りの飲み物を手に取り、リラックスして、一緒に潜りましょう!

ReactJS - Custom Hooks

カスタムフックの理解

無限スクロールに取り組む前に、まずカスタムフックとは何かを理解しましょう。Reactでは、フックは関数コンポーネントからReactの状態とライフサイクル機能に「フック」できる関数です。カスタムフックは、他のフックを使用する関数で、コンポーネント間で共有できます。

カスタムフックをあなたの個人的なスイスアーミーナイフのように考えてください。它们はコンポーネントロジックを再利用可能な関数に抽出し、コードをクリーンでモジュラーにするのに役立ちます。

無限スクロール機能の実装

では、私たちのショーのスター、無限スクロールに取りかりましょう。ソーシャルメディアプラットフォームやニュースサイトでよく遭遇する機能で、スクロールダウンしていくと内容が継続的にロードされるものです。これは、ページ送り不要でスムーズにコンテンツを表示することでユーザーエクスペリエンスを向上させる素晴らしい方法です。

無限スクロールの基本

無限スクロールの核心には、以下の3つの主要なステップがあります:

  1. ユーザーがページの最下部にスクロールしたかどうかを検出
  2. もっとデータをロードするリクエストをトリガー
  3. 新しいデータを既存のコンテンツに追加

これを管理可能なチャンクに分けて、カスタムフックを作成しましょう。

useInfiniteScrollフックの実装

私たちは「useInfiniteScroll」というカスタムフックを作成します。このフックは、いつコンテンツをロードするかを検出するロジックをhandlesし、無限スクロールを実装するために必要な状態と関数を提供します。

以下はフックの基本構造です:

import { useState, useEffect } from 'react';

const useInfiniteScroll = (callback) => {
const [isFetching, setIsFetching] = useState(false);

useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);

useEffect(() => {
if (!isFetching) return;
callback();
}, [isFetching]);

function handleScroll() {
if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight || isFetching) return;
setIsFetching(true);
}

return [isFetching, setIsFetching];
};

export default useInfiniteScroll;

これをピースバイピースに分解しましょう:

  1. useStateuseEffectをReactからインポートします。これらは私たちのカスタムフックの構成要素です。

  2. useInfiniteScrollフックはcallback関数を受け取ります。これはデータをロードする関数です。

  3. useStateを使用してisFetchingという状態変数を作成します。これは現在データをロードしているかどうかをトラッキングします。

  4. 最初のuseEffectは、コンポーネントがマウントされたときにスクロールイベントリスナーを追加し、アンマウントされたときに削除します。これはメモリリークを防ぐために必要です。

  5. 二つ目のuseEffectisFetchingの変更を監視し、trueになったときにコールバック関数を呼び出します。

  6. handleScroll関数は魔法の部分です。ユーザーがページの最下部にスクロールし、データをロードしていない場合にisFetchingをtrueに設定します。

  7. 最後に、isFetchingsetIsFetchingを返し、コンポーネントがこの状態にアクセスし、更新できるようにします。

さて、このフックをコンポーネントでどのように使用するか見てみましょう:

import React, { useState } from 'react';
import useInfiniteScroll from './useInfiniteScroll';

const InfiniteScrollComponent = () => {
const [items, setItems] = useState([]);
const [isFetching, setIsFetching] = useInfiniteScroll(fetchMoreListItems);

function fetchMoreListItems() {
// APIコールのシミュレーション
setTimeout(() => {
setItems(prevItems => ([...prevItems, ...Array(20).fill(0).map((_, i) => ({ id: prevItems.length + i, name: `Item ${prevItems.length + i + 1}` }))]));
setIsFetching(false);
}, 2000);
}

return (
<div>
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
{isFetching && 'Fetching more list items...'}
</div>
);
};

export default InfiniteScrollComponent;

このコンポーネントでは:

  1. useInfiniteScrollフックを使用し、fetchMoreListItems関数を渡します。

  2. fetchMoreListItemsはAPIコールをシミュレーションし、2秒後に20個の新しいアイテムをリストに追加します。

  3. リストアイテムをレンダリングし、isFetchingがtrueの場合はロード中表示メッセージを表示します。

そして、これで完全に機能する無限スクロールの実装が完成しました!

覚えておいてください、カスタムフックの美しさはその再利用性にあります。このuseInfiniteScrollフックは、無限スクロール機能が必要な任意のコンポーネントで使用できます。

結論

カスタムフックはReactの強力な機能で、再利用可能なロジックを作成できます。無限スクロールをカスタムフックとして実装することで、柔軟で再利用可能なソリューションを作成しました。

Reactの旅を続ける中で、カスタムフックを探求し、作成し続けてください。它们はコードをDRY(Don't Repeat Yourself)に保ち、クリーンでモジュラーなコードベースを維持する素晴らしい方法です。

ハッピーコーディング、そしてあなたのスクロールが無限に続きますように!??

メソッド 説明
useInfiniteScroll(callback) 無限スクロールを実装するためのカスタムフック
useState(initialState) 関数コンポーネントに状態を追加するためのReactフック
useEffect(effect, dependencies) 関数コンポーネントでサイドエフェクトを実行するためのReactフック
addEventListener(event, handler) 要素にイベントハンドラを追加するためのWeb API
removeEventListener(event, handler) 要素からイベントハンドラを削除するためのWeb API
setTimeout(callback, delay) 指定された遅延後に関数を実行するためのWeb API

Credits: Image by storyset