React 開発者として、私たちは複数の急速な状態変化を API と同期する必要があるシナリオによく直面します。小さな変更ごとに API 呼び出しを行うのは非効率的であり、クライアントとサーバーの両方に負担がかかる可能性があります。ここで、デバウンスと賢明な状態管理が機能します。この記事では、ペイロードをマージし、API 呼び出しをデバウンスすることで、並列 API 更新呼び出しをキャプチャするカスタム React フックを構築します。
ユーザーが設定や好みを調整できる入力フィールドを想像してください。キーストロークまたは調整ごとに API 呼び出しをトリガーして、新しい状態を保存できます。ユーザーが複数の変更を立て続けに行うと、API リクエストが大量に発生する可能性があります。
デバウンス は、関数が起動できる速度を制限するために使用される手法です。関数をすぐに呼び出すのではなく、一定期間非アクティブになってから実行します。遅延が終了する前に別の電話がかかってくると、タイマーがリセットされます。
React では、useRef は再レンダリングをトリガーせずにレンダリング間で変更可能な値を保持できるようにするフックです。これは本質的に、変更可能な値を保持するコンテナです。
コードを詳しく見て、すべてがどのように構成されるかを理解しましょう。
import { debounce } from "@mui/material"; import { useCallback, useEffect, useRef } from "react"; type DebouncedUpdateParams = { id: string; params: Record<string, any>; }; function useDebouncedUpdate( apiUpdate: (params: DebouncedUpdateParams) => void, delay: number = 300, ) { const accumulatedUpdates = useRef<DebouncedUpdateParams | null>(null); const processUpdates = useRef( debounce(() => { if (accumulatedUpdates.current) { apiUpdate(accumulatedUpdates.current); accumulatedUpdates.current = null; } }, delay), ).current; const handleUpdate = useCallback( (params: DebouncedUpdateParams) => { accumulatedUpdates.current = { id: params.id, params: { ...(accumulatedUpdates.current?.params || {}), ...params.params, }, }; processUpdates(); }, [processUpdates], ); useEffect(() => { return () => { processUpdates.clear(); }; }, [processUpdates]); return handleUpdate; } export default useDebouncedUpdate;
すべての受信アップデートの組み合わせパラメータを保存するために、accumulatedUpdates という useRef を初期化します。
constAccumulatedUpdates = useRef
マテリアル UI のデバウンス ユーティリティを使用して、デバウンス関数 processUpdates を作成します。
const processUpdates = useRef( debounce(() => { if (accumulatedUpdates.current) { apiUpdate(accumulatedUpdates.current); accumulatedUpdates.current = null; } }, delay), ).current; </p> <ul> <li> <strong>processUpdate に useRef を使用する理由</strong> デバウンスされた関数がレンダリングごとに再作成されないようにするために useRef を使用します。これにより、デバウンス タイマーがリセットされます。</li> </ul> <h4> 3. useCallback を使用した更新の処理 </h4> <p>handleUpdate 関数は、更新を蓄積し、デバウンスされた API 呼び出しをトリガーする役割を果たします。<br> </p> <pre class="brush:php;toolbar:false">const handleUpdate = useCallback( (params: DebouncedUpdateParams) => { accumulatedUpdates.current = { id: params.id, params: { ...(accumulatedUpdates.current?.params || {}), ...params.params, }, }; processUpdates(); }, [processUpdates], );
メモリリークを防ぐために、コンポーネントがアンマウントされるときにデバウンス関数をクリアします。
useEffect(() => { return () => { processUpdates.clear(); }; }, [processUpdates]);
コンポーネントでこのフックを使用する方法は次のとおりです:
import React from "react"; import useDebouncedUpdate from "./useDebouncedUpdate"; function SettingsComponent() { const debouncedUpdate = useDebouncedUpdate(updateSettingsApi, 500); const handleChange = (settingName, value) => { debouncedUpdate({ id: "user-settings", params: { [settingName]: value }, }); }; return ( <div> <input type="text" onChange={(e) => handleChange("username", e.target.value)} /> <input type="checkbox" onChange={(e) => handleChange("notifications", e.target.checked)} /> </div> ); } function updateSettingsApi({ id, params }) { // Make your API call here console.log("Updating settings:", params); }
デバウンスと状態蓄積を組み合わせることで、効率的で応答性の高いアプリケーションを作成できます。 useDebouncedUpdate フックにより、急速な変更がまとめてバッチ処理され、不必要な API 呼び出しが削減され、パフォーマンスが向上します。
重要なポイント:
以上がReact アプリで API 呼び出しを最適化した方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。