SWR

29977 ワード

SWR?


「SWR」の名称は、HTTP RFC 5861に知られているHTTPキャッシュ無効ポリシー「時代遅れ-同時-再検証」に由来する.SWRは、まず캐시(스태일)から데이터를 반환、次いでfetch 요청( revalidate:재검증)および최종적으로 최신화된 데이터를 가져오는 전략である.
まずCACHEからデータを返します.次に、リクエストを提出した後、最終的に最新のデータを取得するポリシーです.

SWRの主な目的は


データを取得!

動作原理


その前に、cacheがあれば表示し、cacheがあれば共有し、shareの基準はkeyです.
すなわち、
  • の再検証の間に、まずCACHEのデータが示され、次に最新のデータが再検証される.
  • 優れた機能


    1行のコードだけで、プロジェクト内のデータインポートロジックをシンプル化し、次の驚くべき機能をすぐに使用できます.
  • 高速、軽量、再利用可能なデータインポート
  • 内蔵キャッシュと要求重複除外
  • リアルタイム体験
  • は、送信およびプロトコルによって制限されない
  • .
  • SSR/ISR/SSG support
  • 準備
  • Type Script
  • React Native
  • SWRは、より良い体験を提供するために、速度、正確性、信頼性のさまざまな面をカバーしています.
  • クイックページナビゲーション
  • インタラクティブポーリング
  • データ依存性
  • 焦点再検証
  • ネットワークリカバリ時に
  • を再検証
  • ローカル音楽(OptimisticUI)
  • インテリジェントエラー再試行
  • ページおよびリカバリスクロール位置
  • React Suspense
  • 正式DOSC基本例

    
    const fetcher = (...args) => axios.get(...args).then((res) => res.data);
    
    export default function Profile() {
       const { data, error } = useSWR("/api/user/123", fetcher);
    
       if (error) return <div>failed to load</div>;
       if (!data) return <div>loading...</div>;
       return <div>hello {data.name}!</div>;
     }
    useSWR
    userSWR hookはkey文字列とfetcher関数を受信します.
    key:データの一意の識別子(通常API URL)->キャプチャ
    fetcher:データを返す任意の非同期関数です.
    ネイティブfetchやAxiosなどのツールを使用できます.
    userSWR戻り値
    要求ステータスに基づくデータとエラー.


    Profile.jsx
    const fetcher = (...args) => axios.get(...args).then((res) => res.data);
    
    //useSWR을 호출하는 함수
    function useUser(id) {
      const { data, error } = useSWR(
        `/api/user/${id}`,
        fetcher
        //  {
        //   refreshInterval: 1000,
        // }
      );
    
      return {
        user: data,
        isLoading: !error && !data,
        isError: error,
      };
    }
    
    //Avatar component
    export function Avatar({ id }) {
      const { user, isLoading, isError } = useUser(id);
    
      if (isLoading) return <div>loading... Avatar</div>;
      if (isError) return <div>failed to load... Avatar</div>;
      return (
        <>
          <div>hello {user.name} ! avatar</div>
        </>
      );
    }
    
    //Profile component
    function Profile({ id }) {
      const { user, isLoading, isError } = useUser(id);
    
      if (isLoading) return <div>loading...</div>;
      if (isError) return <div>failed to load</div>;
    
      //데이터 랜더링
      return (
        <>
          <div>hello {user.name}!</div>
          <Avatar id={123} />
        </>
      );
    }
    
    
    //PageComponent
    export const Page = () => {
      return (
        <>
          <Profile id={123} />
          <Avatar id={124} />
        </>
      );
    }

    例では、user関数を呼び出すAvatar、Profile componentが表示されます.
    Profile component内部でAvatar componentを再度呼び出します.
    しかし、プリントされたログを見ると、呼び出しの部分は3つあり、3回も呼び出されず、2回しか呼び出されていない.その理由はurlを共有することです.
    api key name->/api/key/124が一意である場合、応答はキャッシュ内の値に基づいて劣化するため、効率的に使用できます.
    つまり.SWRは、複数のコンポーネントで同じapiを複数回呼び出すことを防止する.

    SWRでのcache


    デフォルトでは、SWRはグローバルキャッシュを使用してすべての構成部品間でデータを格納および共有します.ただし、SWRConfigのproviderオプションを使用してこの操作をカスタマイズすることもできます.

    ネストされている場合、SWR hookはより高いレベルのキャッシュ・プロバイダを使用します.アドバンスドキャッシュプロバイダが存在しない場合は、デフォルトのキャッシュプロバイダによって空のMapに置き換えられます.

    キャッシュプロバイダの作成

    SWRConfigprovider 옵션は、キャッシュプロバイダに戻る関数を受け入れる.では、サプライヤーSWRConfig 경계 내의 모든 SWR hook에서 사용할 수 있습니다.
    import useSWR, { SWRConfig } from 'swr'
    
    function App() {
      return (
        <SWRConfig value={{ provider: () => new Map() }}>
          <Page/>
        </SWRConfig>
      )
    }

    キャッシュをローカルストレージに同期

    function localStorageProvider() {
      
      const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
    
      // app을 unloading하기 전에, 모든 데이터를 `localStorage`에 다시 씁니다.
      console.log("localStorageProvider");
      window.addEventListener("beforeunload", () => {
        const appCache = JSON.stringify(Array.from(map.entries()));
        localStorage.setItem("app-cache", appCache);
      });
    
      // 성능을 위해 여전히 map을 사용해 쓰고 읽습니다.
      return map;
    }
    
    export default function Cache() {
      //Avatar가 useUser라는 훅을 쓰는데 거기는 config 옵션이 하나도 안들어가있다.
      //Page에 감싸놓으면 option으로 동작한다. provider가 provider를 감싸고 있는 형국
      return (
        <SWRConfig
          value={{ refreshInterval: 1000, provider: localStorageProvider }}
        >
          <Page />
        </SWRConfig>
      );
    初期化時には、localStorageのデータをマッピングに復元し、アンインストール前にすべてのデータをlocalStorageに再使用します.
    Cacheとpersistentの例
    function localStorageProvider() {
      // 초기화할 때, `localStorage`의 데이터를 map으로 복구합니다.
      const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
    
      // app을 unloading하기 전에, 모든 데이터를 `localStorage`에 다시 씁니다.
      console.log("localStorageProvider");
      window.addEventListener("beforeunload", () => {
        const appCache = JSON.stringify(Array.from(map.entries()));
        localStorage.setItem("app-cache", appCache);
      });
    
      // 성능을 위해 여전히 map을 사용해 쓰고 읽습니다.
      return map;
    }
    
    export default function Cache() {
      //Avatar가 useUser라는 훅을 쓰는데 거기는 config 옵션이 하나도 안들어가있다.
      //Page에 감싸놓으면 option으로 동작한다. provider가 provider를 감싸고 있는 형국
      return (
        <SWRConfig
          value={{ refreshInterval: 1000, provider: localStorageProvider }}
        >
          <Page />
        </SWRConfig>
      );
    }
    
    const Page = () => {
      const { cache, mutate } = useSWRConfig(); //SWRConfig로 감싸준 덕분에 cache에 직접 도달할수있음.
      console.log("cache", cache);
      return (
        <div>
          <Avatar id={1212} />
          <button
            onClick={() => {
              mutate("/api/user/1212"); // -> 이키로 저장되어있는 fetcher를 다시 실행한다.
              //이키로 데이터뿐만아니라 fetcher도 저장되어있어 새로운값을 불러오는데 사용할수있다.
              console.log(`check : ${JSON.stringify(cache.get("/api/user/1212"))}`); // cache안에 key값으로 객체를 끌어올수 있다.
            }}
          >
            check
          </button>
        </div>
      );
    };