remix-client-cache

GitHub Repo stars npm GitHub npm npm GitHub top language

重要資訊

此程式庫現在是 React Router 生態系統的一部分,並在 React Router 之上運行。它應該與 remix.run 相容,但如果您遇到問題,1.1.0 版本是最後一個與 remix.run 相容的版本。

remix-client-cache 是一個功能強大且輕巧的程式庫,專為 Remix.run 設計,可使用 clientLoaders 在客戶端快取您的伺服器載入器資料。

預設情況下,它使用過時時重新驗證的策略,並在從伺服器載入後熱交換您的過時資訊。它還允許您使特定金鑰或多個金鑰的快取失效。

它允許您傳入您選擇的介面卡來快取您的資料。

它帶有一個預設介面卡,使用記憶體內儲存來快取您的資料。

對 localStorage、sessionStorage 和 localforage 套件的第一方支援。您可以將它們作為 configureGlobalCache 的參數提供。

安裝

npm install remix-client-cache

基本用法

這是 remix-client-cache 與預設記憶體內介面卡一起使用的範例。

import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { ClientLoaderFunctionArgs } from "@remix-run/react";

import { cacheClientLoader, useCachedLoaderData } from "remix-client-cache";

export const loader = async ({ params }: LoaderFunctionArgs) => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/users/${params.user}`
  );
  const user = await response.json();
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return json({ user: { ...user, description: Math.random() } });
};


// Caches the loader data on the client
export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader(args);
  
// make sure you turn this flag on
clientLoader.hydrate = true;

export default function Index() {
  // The data is automatically cached for you and hot swapped when refetched
  const { user } = useCachedLoaderData<typeof loader>(); 

  return (
    <div>
      {user.name} <hr /> {user.email}
      <hr />
      {user.username}
      <hr />
      {user.website} <hr />
      {user.description} 
    </div>
  );
}

快取介面卡

該程式庫匯出一個您需要實作的介面,以建立您自己的快取介面卡。該介面稱為 CacheAdapter。它與 Storage 的介面非常相似,並且要求您具有以下方法

  • getItem:接收一個金鑰,並傳回一個 promise,該 promise 會解析為儲存在該金鑰處的值
  • setItem:接收一個金鑰和一個值,並傳回一個 promise,該 promise 會在值儲存時解析
  • removeItem:接收一個金鑰,並傳回一個 promise,該 promise 會在值移除時解析

cacheLoaderData 將使用程式庫隨附的預設記憶體快取介面卡。如果您想要進階的使用案例,請確保您提供的介面卡實作了 CacheAdapter 介面。

// Inside your entry.client.tsx file 
import { RemixBrowser } from "@remix-run/react";
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";

import { configureGlobalCache } from "remix-client-cache";

// You can use the configureGlobalCache function to override the libraries default in-memory cache adapter
configureGlobalCache(() => localStorage); // uses localStorage as the cache adapter

startTransition(() => {
  hydrateRoot(
    document,
    <StrictMode>
      <RemixBrowser />
    </StrictMode>
  );
});

您可以使用 configureGlobalCache 函數來覆寫程式庫的預設記憶體內快取介面卡。它會全域切換為您提供給它的任何介面卡。

如果您想要每個路由介面卡,您可以使用 createCacheAdapter 來建立介面卡,並將其提供給您的掛鉤和函數。


import { createCacheAdapter, useCachedLoaderData } from "remix-client-cache";

const { adapter } = createCacheAdapter(() => localStorage); // uses localStorage as the cache adapter


// Caches the loader data on the client
export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader(args, { 
  // We pass our custom adapter to the clientLoader
  adapter
});
  
// make sure you turn this flag on
clientLoader.hydrate = true;

export default function Index() {
  const { user } = useCachedLoaderData<typeof loader>({ 
    // We use the adapter returned by the createCacheAdapter function
    adapter
  });

  return (
    <div>
      {user.name} <hr /> {user.email}
      <hr />
      {user.username}
      <hr />
      {user.website} <hr />
      {user.description} 
    </div>
  );
}


以下是一些如何將程式庫與不同的全域介面卡一起使用的範例。

configureGlobalCache(() => localStorage); // uses localStorage as the cache adapter
configureGlobalCache(() => sessionStorage); // uses sessionStorage as the cache adapter
configureGlobalCache(() => localforage); // uses localforage as the cache adapter

也適用於不同的每個路由介面卡

const { adapter } = createCacheAdapter(() => localStorage); // uses localStorage as the cache adapter
const { adapter } = createCacheAdapter(() => sessionStorage); // uses sessionStorage as the cache adapter
const { adapter } = createCacheAdapter(() => localforage); // uses localforage as the cache adapter

假設您想要使用一個自訂介面卡,使用資料庫來儲存資料。

您可以透過實作 CacheAdapter 介面,並將其傳遞給 configureGlobalCachecreateCacheAdapter 函數來做到這一點。

class DatabaseAdapter implements CacheAdapter {
  async getItem(key: string) {
    // get the item from the database
  }

  async setItem(key: string, value: string) {
    // set the item in the database
  }

  async removeItem(key: string) {
    // remove the item from the database
  }
}

configureGlobalCache(() => new DatabaseAdapter()); // uses your custom adapter as the cache adapter globally
const { adapter } = createCacheAdapter(() => new DatabaseAdapter()); // uses your custom adapter as the cache adapter per route

API

createCacheAdapter

建立快取介面卡並傳回它的函數。它接收一個引數,即用於儲存資料的 adapter

import { createCacheAdapter } from "remix-client-cache";

const { adapter } = createCacheAdapter(() => localStorage); // uses localStorage as the cache adapter

configureGlobalCache

設定全域快取介面卡的函數。它接收一個引數,即用於儲存資料的 adapter

import { configureGlobalCache } from "remix-client-cache";

configureGlobalCache(() => localStorage); // uses localStorage as the cache adapter

cacheClientLoader

用於快取從載入器傳輸到您的元件的資料,使用 clientLoader 匯出。

它接收兩個引數,第一個是傳遞到 clientLoader 函數的 ClientLoaderFunctionArgs 物件,第二個是具有以下屬性的物件

  • type - 告知客戶端載入器是否應使用正常的快取機制,在其中儲存資料並提前傳回該資料,而不是重新擷取,或者是否應使用 staleWhileRevalidate 機制,在其中傳回快取的資料並在背景中重新擷取。
  • key - 用於在快取中儲存資料的金鑰。預設為包含搜尋參數和雜湊的目前路由路徑。(例如 /user/1?name=John#profile)
  • adapter - 用於儲存資料的快取介面卡。預設為程式庫隨附的記憶體內介面卡。
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { ClientLoaderFunctionArgs } from "@remix-run/react"; 
import { cacheClientLoader, useCachedLoaderData } from "remix-client-cache";

export const loader = async ({ params }: LoaderFunctionArgs) => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/users/${params.user}`
  );
  const user = await response.json();
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return json({ user: { ...user, description: Math.random() } });
};

export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader(args, {
  type: "swr", // default is swr, can also be set to normal
  key: "/user/1" // default is the current route path including search params and hashes
  adapter: () => localStorage // default is the in memory adapter, can be anything your wish
});
clientLoader.hydrate = true;

decacheClientLoader

用於移除從載入器傳輸到您的元件的資料,使用 clientLoader 匯出。

import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { ClientLoaderFunctionArgs } from "@remix-run/react"; 
import { decacheClientLoader, useCachedLoaderData } from "remix-client-cache";

export const loader = async ({ params }: LoaderFunctionArgs) => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/users/${params.user}`
  );
  const user = await response.json();
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return json({ user: { ...user, description: Math.random() } });
};
// The data is cached here
export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader;
clientLoader.hydrate = true;
// It is de-cached after a successful action submission via the clientAction export
export const clientAction = decacheClientLoader;

接收一個可選的物件,其中包含以下屬性

  • key - 用於在快取中儲存資料的金鑰。
  • adapter - 用於儲存資料的快取介面卡。

useCachedLoaderData

可用於從 clientLoader 匯出中取得快取資料的掛鉤。必須與 cacheClientLoader 一起使用,因為從 cacheClientLoader 傳回的資料經過擴充,可以在考慮 useCachedLoaderData 的情況下使用,而不是標準的 useLoaderData 掛鉤。

import { useCachedLoaderData } from "remix-client-cache";

// Must be used together with cacheClientLoader
export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader(args, "swr");
clientLoader.hydrate = true;

export default function Index() {
  // The data is automatically cached for you and hot swapped when refetched
  const { user } = useCachedLoaderData<typeof loader>(); 

  return (
    <div>
      {user.name} <hr /> {user.email}
      <hr />
      {user.username}
      <hr />
      {user.website} <hr />
      {user.description} 
    </div>
  );
}

接收一個可選的物件,其中包含以下屬性

  • adapter - 用於儲存資料的快取介面卡。預設為程式庫隨附的記憶體內介面卡。

useSwrData

用於取得一個 SWR 元件的掛鉤,該元件會為您熱交換資料。它接收一個引數,即由 useCachedLoaderDatauseLoaderData 掛鉤傳回的 loaderData。

import { useCachedLoaderData, useSwrData } from "remix-client-cache";

export const clientLoader = (args: ClientLoaderFunctionArgs) => cacheClientLoader(args);
clientLoader.hydrate = true;

export default function Index() {
  // We do not destructure the data so we can pass in the object into the useSwrData hook
  const loaderData = useLoaderData<typeof loader>(); 
  // You can also use useCachedLoaderData hook with the useSwrData hook
  const loaderData = useCachedLoaderData<typeof loader>(); 
  // Pass the loader data into the hook and the component will handle everything else for you
  const SWR = useSwrData(loaderData);

  return (
    <SWR>
      {/** Hot swapped automatically */}
      {({ user }) => (
        <div>
          {data.name} <hr /> {data.email}
          <hr />
          {data.username}
          <hr />
          {data.website} <hr />
          {data.description} 
        </div>
      )}
    </SWR>
  );
}

invalidateCache

可用於使特定金鑰的快取失效的實用程式函數。它接收一個引數,即用於在快取中儲存資料的 key。也可以是金鑰陣列

import { invalidateCache } from "remix-client-cache";

invalidateCache("/user/1"); // invalidates the cache for the /user/1 route

請記住,這只能在客戶端上使用,因此可以在 clientLoaderclientAction 匯出或元件本身中使用。

useCacheInvalidator

傳回一個函數的掛鉤,該函數可用於使特定金鑰的快取失效。它接收一個引數,即用於在快取中儲存資料的 key。也可以是金鑰陣列

import { useCacheInvalidator } from "remix-client-cache";

export default function Index() {
  const { invalidateCache } = useCacheInvalidator(); 

  return (
    <div>
      // invalidates the cache for the /user/1 route
      <button onClick={ () => invalidateCache("/user/1") }>Invalidate cache</button>
    </div>
  );
}

支援

如果您喜歡該專案,請考慮在 Github 上給予 ⭐️ 來支援我們。

許可

MIT

錯誤

如果您發現錯誤,請在 我們在 GitHub 上的問題追蹤器 上提交問題

貢獻

感謝您考慮為 remix-client-cache 做出貢獻!我們歡迎任何大小的貢獻,包括錯誤報告、功能請求、文件改進或程式碼變更。

若要開始使用,請 fork 此儲存庫並在新的分支中進行變更。準備好提交變更後,請開啟一個 pull request,其中清楚說明您的變更以及任何相關問題或 pull request。

請注意,所有貢獻均受我們的 行為準則 約束。透過參與,您應遵守此準則。

我們感謝您為 remix-client-cache 做出貢獻,並幫助使其成為社群更好的工具,這表示您付出的時間和努力!