77![ npm] ( https://img.shields.io/npm/dm/remix-client-cache?style=plastic )
88![ GitHub top language] ( https://img.shields.io/github/languages/top/Code-Forge-Net/remix-client-cache?style=plastic )
99
10- <img style =" display : block ; margin : 0 auto ;" src =" ./assets/remix-cache.png " height =" 300px " align =" middle " />
10+ <img style =" display : block ; margin : 0 auto ;" src =" ./assets/remix-cache.png " height =" 300px " align =" middle " />
1111
12- # Important information
13-
14- This library is now a part of the React Router ecosystem and runs on top of React Router. It should be compatible with remix.run but if you're having issues version
15- 1.1.0 is the last version that will work with remix.run.
1612
17-
18- remix-client-cache is a powerful and lightweight library made for Remix.run to cache your server loader data on the client using clientLoaders.
13+ remix-client-cache is a powerful and lightweight library made for react-router v7 framework mode to cache your server loader data on the client using clientLoaders.
1914
2015By default it uses the stale while revalidate strategy and hot swaps your stale info once loaded from the server. It also allows you to invalidate the cache for a specific key or multiple keys.
2116
@@ -25,40 +20,41 @@ It comes with a default adapter that uses in memory storage to cache your data.
2520
2621First party support for localStorage, sessionStorage and localforage packages. You can just provide them as the argument to ` configureGlobalCache ` .
2722
23+ # Important information
24+
25+ This library is now a part of the React Router ecosystem and runs on top of React Router. It should be compatible with remix.run but if you're having issues version
26+ 1.1.0 is the last version that will work with remix.run.
27+
2828## Install
2929
30- npm install remix-client-cache
30+ ``` bash
31+ npm install remix-client-cache
32+ ```
3133
3234## Basic usage
3335
3436Here is an example usage of remix-client-cache with the default in memory adapter.
3537
36- ``` tsx
37- import { json , type LoaderFunctionArgs } from " @remix-run/node " ;
38- import { ClientLoaderFunctionArgs } from " @ remix-run/react " ;
38+ ``` tsx
39+ import type { Route } from " ./+types/_index " ;
40+ import { createClientLoaderCache , CacheRoute } from " remix-client-cache " ;
3941
40- import { cacheClientLoader , useCachedLoaderData } from " remix-client-cache" ;
41-
42- export const loader = async ({ params }: LoaderFunctionArgs ) => {
42+ // Some slow server loader
43+ export const loader = async ({ params }: Route .LoaderArgs ) => {
4344 const response = await fetch (
4445 ` https://jsonplaceholder.typicode.com/users/${params .user } `
4546 );
4647 const user = await response .json ();
4748 await new Promise ((resolve ) => setTimeout (resolve , 1000 ));
48- return json ( { user: { ... user , description: Math .random () } }) ;
49+ return { user: { ... user , description: Math .random () } };
4950};
5051
51-
5252// Caches the loader data on the client
53- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args );
54-
55- // make sure you turn this flag on
56- clientLoader .hydrate = true ;
53+ export const clientLoader = createClientLoaderCache <Route .ClientLoaderArgs >();
5754
58- export default function Index() {
5955 // The data is automatically cached for you and hot swapped when refetched
60- const { user } = useCachedLoaderData < typeof loader >();
61-
56+ export default CacheRoute ( function Index({ loaderData } : Route . LoaderData ) {
57+ const { user } = loaderData ;
6258 return (
6359 <div >
6460 { user .name } <hr /> { user .email }
@@ -69,7 +65,7 @@ export default function Index() {
6965 { user .description }
7066 </div >
7167 );
72- }
68+ })
7369
7470```
7571
@@ -86,7 +82,7 @@ The `cacheLoaderData` will use the default memory cache adapter that comes with
8682
8783``` ts
8884// Inside your entry.client.tsx file
89- import { RemixBrowser } from " @remix-run/react " ;
85+ import { HydratedRouter } from " react-router/dom "
9086import { startTransition , StrictMode } from " react" ;
9187import { hydrateRoot } from " react-dom/client" ;
9288
@@ -99,7 +95,7 @@ startTransition(() => {
9995 hydrateRoot (
10096 document ,
10197 <StrictMode >
102- < RemixBrowser / >
98+ < HydratedRouter / >
10399 < / StrictMode >
104100 );
105101});
@@ -110,15 +106,15 @@ You can use the `configureGlobalCache` function to override the libraries defaul
110106
111107If you want to have a per route adapter you can use the ` createCacheAdapter ` to create an adapter and provide it to your hooks and functions.
112108
113- ``` ts
109+ ``` tsx
114110
115111import { createCacheAdapter , useCachedLoaderData } from " remix-client-cache" ;
112+ import type { Route } from " ./+types/_index" ;
116113
117114const { adapter } = createCacheAdapter (() => localStorage ); // uses localStorage as the cache adapter
118115
119-
120116// Caches the loader data on the client
121- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args , {
117+ export const clientLoader = (args : Route . ClientLoaderArgs ) => cacheClientLoader (args , {
122118 // We pass our custom adapter to the clientLoader
123119 adapter
124120});
@@ -142,8 +138,7 @@ export default function Index() {
142138 { user .description }
143139 </div >
144140 );
145- }
146-
141+ }
147142
148143```
149144
@@ -189,6 +184,32 @@ const { adapter } = createCacheAdapter(() => new DatabaseAdapter()); // uses you
189184
190185## API's
191186
187+ ### CacheRoute
188+ Wrapper function that wraps your component and provides the loader data to it. It takes two arguments, the component that is wrapped as the first one, and the config options as the second (like the adapter to use).
189+
190+ ``` tsx
191+ import { CacheRoute , createClientLoaderCache } from " remix-client-cache" ;
192+ import type { Route } from " ./+types/_index" ;
193+
194+ // Caches the loader data on the client
195+ export const clientLoader = createClientLoaderCache <Route .ClientLoaderArgs >();
196+
197+ // Wraps the component and provides the loader data to it that gets hot swapped behind the scenes
198+ export default CacheRoute (function Index({ loaderData }: Route .LoaderData ) {
199+ const { user } = loaderData ;
200+ return (
201+ <div >
202+ { user .name } <hr /> { user .email }
203+ <hr />
204+ { user .username }
205+ <hr />
206+ { user .website } <hr />
207+ { user .description }
208+ </div >
209+ );
210+ })
211+ ```
212+
192213### createCacheAdapter
193214
194215Function that creates a cache adapter and returns it. It takes one argument, the ` adapter ` that is used to store the data.
@@ -222,20 +243,20 @@ It takes two arguments, the first one is the `ClientLoaderFunctionArgs` object t
222243
223244
224245``` tsx
225- import { json , type LoaderFunctionArgs } from " @remix-run/node" ;
226- import { ClientLoaderFunctionArgs } from " @remix-run/react" ;
246+
227247import { cacheClientLoader , useCachedLoaderData } from " remix-client-cache" ;
248+ import type { Route } from " ./+types/_index" ;
228249
229- export const loader = async ({ params }: LoaderFunctionArgs ) => {
250+ export const loader = async ({ params }: Route . LoaderArgs ) => {
230251 const response = await fetch (
231252 ` https://jsonplaceholder.typicode.com/users/${params .user } `
232253 );
233254 const user = await response .json ();
234255 await new Promise ((resolve ) => setTimeout (resolve , 1000 ));
235- return json ( { user: { ... user , description: Math .random () } }) ;
256+ return { user: { ... user , description: Math .random () } };
236257};
237258
238- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args , {
259+ export const clientLoader = (args : Route . ClientLoaderArgs ) => cacheClientLoader (args , {
239260 type: " swr" , // default is swr, can also be set to normal
240261 key: " /user/1" // default is the current route path including search params and hashes
241262 adapter : () => localStorage // default is the in memory adapter, can be anything your wish
@@ -250,11 +271,12 @@ Creates everything needed to cache the data via clientLoader, behind the scenes
250271
251272``` tsx
252273import { createClientLoaderCache , cacheClientLoader } from " remix-client-cache" ;
274+ import type { Route } from " ./+types/_index" ;
253275
254276export const clientLoader = createClientLoaderCache ();
255277
256278// above is equivalent to:
257- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args );
279+ export const clientLoader = (args : Route . ClientLoaderArgs ) => cacheClientLoader < Route . ClientLoaderArgs > (args );
258280clientLoader .hydrate = true ;
259281```
260282
@@ -263,20 +285,19 @@ clientLoader.hydrate = true;
263285Used to remove the data that is piped from the loader to your component using the ` clientLoader ` export.
264286
265287``` tsx
266- import { json , type LoaderFunctionArgs } from " @remix-run/node" ;
267- import { ClientLoaderFunctionArgs } from " @remix-run/react" ;
268288import { decacheClientLoader , useCachedLoaderData } from " remix-client-cache" ;
289+ import type { Route } from " ./+types/_index" ;
269290
270- export const loader = async ({ params }: LoaderFunctionArgs ) => {
291+ export const loader = async ({ params }: Route . LoaderArgs ) => {
271292 const response = await fetch (
272293 ` https://jsonplaceholder.typicode.com/users/${params .user } `
273294 );
274295 const user = await response .json ();
275296 await new Promise ((resolve ) => setTimeout (resolve , 1000 ));
276- return json ( { user: { ... user , description: Math .random () } }) ;
297+ return { user: { ... user , description: Math .random () } };
277298};
278299// The data is cached here
279- export const clientLoader = ( args : ClientLoaderFunctionArgs ) => cacheClientLoader ;
300+ export const clientLoader = createClientLoaderCache < Route . ClientLoaderArgs >() ;
280301clientLoader .hydrate = true ;
281302// It is de-cached after a successful action submission via the clientAction export
282303export const clientAction = decacheClientLoader ;
@@ -296,9 +317,10 @@ the `cacheClientLoader` is augmented to work with `useCachedLoaderData` in mind
296317
297318``` tsx
298319import { useCachedLoaderData } from " remix-client-cache" ;
320+ import type { Route } from " ./+types/_index" ;
299321
300322// Must be used together with cacheClientLoader
301- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args , " swr" );
323+ export const clientLoader = (args : Route . ClientLoaderArgs ) => cacheClientLoader < Route . ClientLoaderArgs > (args , " swr" );
302324clientLoader .hydrate = true ;
303325
304326export default function Index() {
@@ -329,8 +351,9 @@ Hook used to get an SWR component that hot swaps the data for you. It takes one
329351
330352``` tsx
331353import { useCachedLoaderData , useSwrData } from " remix-client-cache" ;
354+ import type { Route } from " ./+types/_index" ;
332355
333- export const clientLoader = (args : ClientLoaderFunctionArgs ) => cacheClientLoader (args );
356+ export const clientLoader = (args : Route . ClientLoaderArgs ) => cacheClientLoader < Route . ClientLoaderArgs > (args );
334357clientLoader .hydrate = true ;
335358
336359export default function Index() {
@@ -391,6 +414,13 @@ export default function Index() {
391414}
392415```
393416
417+ ## Migration from v2 to v3
418+
419+ Some of the previous functions that didn't require type info now require ` Route.ClientLoaderArgs ` type info. Providing this info should be enough to get you up and running.
420+
421+
422+
423+
394424## Support
395425
396426If you like the project, please consider supporting us by giving a ⭐️ on Github.
0 commit comments