Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

✨ If you know how to use Fetch, you know how to use Fetchye [fetch-yae]. Simple React Hooks, Centralized Cache, Infinitely Extensible.

License

NotificationsYou must be signed in to change notification settings

americanexpress/fetchye

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Fetchye - One Amex

If you know how to use Fetch, you know how to use Fetchye [fetch-yae]. Simple React Hooks, Centralized Cache, Infinitely Extensible.

// ...import{useFetchye}from'fetchye';constMyComponent=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/profile');return(!isLoading&&(<p>{data.body.name}</p>));};

📖 Table of Contents

✨ Features

  • ES6 Fetch powered by React Hooks
  • Pure React or Redux Shared Cache modes available
  • Headless per-Hook Cache Mode available
  • SSR-friendly

⬇️ Install & Setup

Contents

Quick Install

💡 Makes use of Headless per-Hook Cache Mode

Pros

  • Painless and Quick

Cons

  • No shared caching
  • No de-duplication of API calls

Just install and douseFetchye. Thats it!

npm i -S fetchye
// ...import{useFetchye}from'fetchye';constMyComponent=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/profile');return(!isLoading&&(<p>{data?.body.name}</p>));};

🏖️Try this out on Codesandbox

FetchyeProvider Install

💡 When you want a central cache but no extra dependencies

Pros

  • Easy
  • Shared Cache
  • De-duplication of API calls

Cons

  • No Redux Dev Tools for debugging and cache inspection
  • Limited centralized server-side data hydration support

Installfetchye:

npm i -S fetchye

Add the<FetchyeProvider /> component:

import{FetchyeProvider}from'fetchye';constParentComponent=({ children})=>(<FetchyeProvider>{/* Use your Router to supply children components containing useFetchye */}{children}</FetchyeProvider>);

In a child React Component, douseFetchye queries:

// ...import{useFetchye}from'fetchye';constMyComponent=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/profile');return(!isLoading&&(<p>{data?.body.name}</p>));};

🏖️Try this out on Codesandbox

FetchyeReduxProvider Install

💡 When you want a central cache integrated with a Redux based project

Pros

  • Easy if you know Redux
  • Shared Cache
  • De-duplication of API calls
  • Redux Dev Tools for debugging and cache inspection
  • Excellent centralized server-side data hydration support

Cons

  • More steps and dependencies

Addfetchye and its needed optional dependencies:

npm i -S fetchye redux react-redux

Add the<FetchyeReduxProvider /> component under the Redux<Provider />:

importReactfrom'react';import{createStore}from'redux';import{Provider}from'react-redux';import{FetchyeReduxProvider}from'fetchye-redux-provider';import{SimpleCache}from'fetchye';constfetchyeCache=SimpleCache({// Need to tell Fetchye where the cache reducer will be locatedcacheSelector:(state)=>state,});conststore=createStore(fetchyeCache.reducer);constParentComponent=({ children})=>(<Providerstore={store}><FetchyeReduxProvidercache={fetchyeCache}>{/* Use your Router to supply children components containing useFetchye */}{children}</FetchyeReduxProvider></Provider>);

In a child React Component, douseFetchye queries:

// ...import{useFetchye}from'fetchye';constMyComponent=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/profile');return(!isLoading&&(<p>{data.body.name}</p>));};

🏖️Try this out on Codesandbox

One App Install

💡 For when you use theOne App Micro-Frontend Framework

Pros

  • Shared Cache
  • De-duplication of API calls
  • Redux Dev Tools for debugging and cache inspection
  • Excellent centralized server-side data hydration support
  • Shared Cache between Micro Frontend Holocron Modules
  • Immutable Redux State
  • Minimal configuration

Cons

  • More steps and dependencies
npm i -S fetchye fetchye-one-app

fetchye-one-app provides pre-configuredprovider,cache,oneFetchye andoneCacheSelector to ensure that all modules use the same cache and reduce the chance for cache misses. These all have restricted APIs to reduce the chance for misconfiguration however if you require more control/customization useImmutableCache,FetchyeReduxProvider andmakeServerFetchye. Please bear in mind that this can impact modules which are do not use the same configuration.

Add the<OneFetchyeProvider /> component fromfetchye-one-app to your Root Holocron Module, and add the reducer fromOneCache scoped underfetchye:

// ...import{combineReducers}from'redux-immutable';import{OneFetchyeProvider,OneCache}from'fetchye-one-app';constMyModuleRoot=({ children})=>(<>{/* OneFetchyeProvider is configured to use OneCache */}<OneFetchyeProvider>{/* Use your Router to supply children components containing useFetchye */}{children}</OneFetchyeProvider></>);// ...MyModuleRoot.holocron={name:'my-module-root',reducer:combineReducers({// ensure you scope the reducer under "fetchye", this is important// to ensure that child modules can make use of the single cachefetchye:OneCache().reducer,// ... other reducers}),};

In a child React Component or Holocron Module, douseFetchye queries:

// ...import{useFetchye}from'fetchye';constMyComponent=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/profile');return(!isLoading&&(<p>{data?.body.name}</p>));};

This minimal configuration works as the provider, cache and makeOneServerFetchye, mentioned later, all follow expected conventions.

🤹‍ Usage

Real-World Example

importReactfrom'react';import{useFetchye}from'fetchye';constBookList=({ genre})=>{const{ isLoading, error, data}=useFetchye(`http://example.com/api/books/?genre=${genre}`,{headers:{'X-Some-Tracer-Id':1234,},});if(isLoading){return(<p>Loading...</p>);}if(error||data.status!==200){return(<p>Oops!</p>);}return(<><h1>Books by{genre}</h1><ul>{data.body.map((book)=>(<likey={book.id}>{book.title} by{book.author}</li>))}</ul></>);};

Deferred execution

When you need to delay execution of auseFetchye call, you may use{ defer: true } option. This is great for forms:

importReactfrom'react';import{useFetchye}from'fetchye';constNewBookForm=()=>{const{ formData, onChange}=useSomeFormHandler();const{ isLoading, run}=useFetchye('http://example.com/api/books',{// include defer heredefer:true,method:'POST',headers:{'Content-Type':'application/json',},body:JSON.stringify({      ...formData,}),});constonSubmit=async(event)=>{event.preventDefault();const{ data, error}=awaitrun();// Check to make sure no error and data.status === 200 for success};return(<formonSubmit={onSubmit}>{/* ...form elements using onChange */}{/* Hide Submit button when sending POST request */}{!isLoading&&<buttontype="submit">Submit</button>}</form>);};

Abort Inflight Requests

When you neeed to abort the execution of requests inflight, passing a signal from theAbort Controller API touseFetchye as an option will enable this.

ConsideringuseFetchye is a wrapper around fetch, passing a signal is the same and provides the same functionality as demonstrated below.

importReact,{useEffect}from'react';import{useFetchye}from'fetchye';constAbortComponent=()=>{constcontroller=newAbortController();useFetchye('http://example.com/api/books',{signal:controller.signal});useEffect(()=>()=>controller.abort(),[]);return(<div><h1>abortable component</h1></div>);};

Instead of setting up auseEffect within the component it's possible to pass a hook to signal using packages such asuse-unmount-signal.

Sequential API Execution

Passing the 'isLoading' value from one useFetchye call to the 'defer' field of the next will prevent the second call from being made until the first has loaded.

To ensure the second api call is properly formed, you should also check that the data you expect from the first call exists:

importReactfrom'react';import{useFetchye}from'fetchye';constMyFavoriteBook=()=>{const{isLoading:loadingProfile,error:profileError,data:profile,}=useFetchye('http://example.com/api/profile');constprofileHasBookId=!loadingProfile&&profile?.body?.favoriteBookId;const{isLoading:loadingBook,error:bookError,data:favoriteBook,}=useFetchye('http://example.com/api/books',{defer:!profileHasBookId,method:'POST',body:JSON.stringify({bookId:profile?.body?.favoriteBookId,}),});if(loadingProfile){return(<p>Loading Profile...</p>);}if(profileError||profile.status!==200){return(<p>Oops!</p>);}if(loadingBook){return(<p>Loading Favourite Book...</p>);}if(bookError||favoriteBook.status!==200){return(<p>Oops!</p>);}return(favoriteBook.status===200&&(<><h1>My Favorite Book</h1><h2>{favoriteBook.body.title}</h2></>));};

Alternatively, you can pass a function as the first parameter to useFetchye, if this function throws an exception, or returns a falsy value, the call will automatically be 'deferred' until the function does not throw.

This only works if the sequential data is passed to the second call in the url.

In this example, the function will throwCannot read properties of undefined when trying to access 'favoriteBookId' in the non-existent body of the profile:

importReactfrom'react';import{useFetchye}from'fetchye';constMyFavoriteBook=()=>{const{isLoading:loadingProfile,error:profileError,data:profile,}=useFetchye('http://example.com/api/profile');const{isLoading:loadingBook,error:bookError,data:favoriteBook,}=useFetchye(()=>`http://example.com/api/books/${profile.body.favoriteBookId}`);if(loadingProfile){return(<p>Loading Profile...</p>);}if(profileError||profile.status!==200){return(<p>Oops!</p>);}if(loadingBook){return(<p>Loading Favourite Book...</p>);}if(bookError||favoriteBook.status!==200){return(<p>Oops!</p>);}return(favoriteBook.status===200&&(<><h1>My Favorite Book</h1><h2>{favoriteBook.body.title}</h2></>));};

Refreshing

importReactfrom'react';import{useFetchye}from'fetchye';constBookList=({ genre})=>{const{    isLoading,data:booksData,    run,}=useFetchye(`http://example.com/api/books/?genre=${genre}`);if(isLoading){return(<p>Loading...</p>);}return(<>{/* Render booksData */}<buttontype="button"onClick={()=>run()}>Refresh</button></>);};

Custom Fetcher

Custom fetchers allow for creating reusable data fetching logic for specific APIs or custom needs. They allow for a centrally providedfetchClient which wraps that client on a peruseFetchye request basis.

importReactfrom'react';import{useFetchye}from'fetchye';constgraphqlFetcher=async(fetchClient,key,options)=>{letres;letpayload;leterror;try{res=awaitfetchClient('https://example.com/graphql',{      ...options,method:'POST',headers:{'X-Correlation-Id':12345,'Content-Type':'application/json',},// The key contains the GraphQL object request rather than a URL in this casebody:JSON.stringify(key),});// GraphQL Responseconst{ data, errors}=awaitres.json();// Pass through GraphQL Datapayload={      data,ok:res.ok,status:res.status,};// Assign GraphQL errors to errorerror=errors;}catch(requestError){// eslint-disable-next-line no-console -- error useful to developer in specific error caseconsole.error(requestError);error=requestError;}return{    payload,    error,};};constBookList=({ genre})=>{const{ isLoading,data:booksData, run}=useFetchye({query:`      query BookList($genre: Genre) {        book(genre: $genre) {          title          author        }      }      `,variables:{ genre},},{},graphqlFetcher);if(isLoading){return(<p>Loading...</p>);}return(<>{/* Render booksData */}<buttontype="button"onClick={()=>run()}>Refresh</button></>);};

Controlling the Cache Key

By passing mapKeyToCacheKey as an option you can customize the cacheKey without affecting the key. This allows you to control the cacheKey directly to enable advanced behaviour in your cache.

Note: This option can lead to unexpected behaviour in many cases. Customizing the cacheKey in this way could lead to accidental collisions that lead to fetchye providing the 'wrong' cache for some of your calls, or unnecessary cache-misses causing significant performance degradation.

In this example the client can dynamically switch between http and https depending on the needs of the user, but should keep the same cache key.

Therefore, mapKeyToCacheKey is defined to transform the url to always have the same protocol in the cacheKey.

importReactfrom'react';import{useFetchye}from'fetchye';constBookList=({ ssl})=>{const{ isLoading, data}=useFetchye(`${ssl ?'https' :'http'}://example.com/api/books/`,{mapKeyToCacheKey:(key)=>key.replace('https://','http://'),});if(isLoading){return(<p>Loading...</p>);}return({/* Render data */});};

Passing dynamic headers

When you call therun function returned from useFetchye, it will use the values last rendered into the hook.

This means any correlationId, timestamp, or any other unique dynamic header you might want sent to the server will use its previous value.

To overcome this, you can specify a function instead of aheaders object in the options.

This function will be called, to re-make the headers just before an API call is made, even when you callrun.

Note: If you don't want the dynamic headers to result in a cache miss, you must remove the keys of the dynamic headers from the options usingmapOptionsToKey (see example below that uses theignoreHeadersByKey helper).

importReactfrom'react';import{useFetchye,ignoreHeadersByKey}from'fetchye';importuuidfrom'uuid';constBookList=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/books/',{// remove the 'correlationId' header from the headers, as its the only dynamic headermapOptionsToKey:ignoreHeadersByKey(['correlationId']),headers:()=>({// static headers are still fine, and can be specified here like normalstaticHeader:'staticValue',// This header will be generated fresh for every call out of the systemcorrelationId:uuid(),}),});if(isLoading){return(<p>Loading...</p>);}return({/* Render data */});};exportdefaultBookList;

SSR

One App SSR

UsingoneFetchye fromfetchye-one-app ensures that the cache will always be configured correctly.

importReactfrom'react';import{useFetchye}from'fetchye';import{oneFetchye}from'fetchye-one-app';constBookList=()=>{const{ isLoading, data}=useFetchye('http://example.com/api/books/');if(isLoading){return(<p>Loading...</p>);}return({/* Render data */});};BookList.holocron={loadModuleData:async({store:{ dispatch}})=>{if(global.BROWSER){return;}// oneFetchye has same arguments as useFetchye// dispatches events into the server side Redux storeawaitdispatch(oneFetchye('http://example.com/api/books/'));},};exportdefaultBookList;

Next.JS SSR

import{useFetchye,makeServerFetchye,SimpleCache}from'fetchye';constcache=SimpleCache();// Codesandbox takes a second to get Next.JS started...exportdefaultfunctionIndexPage({ initialBookList}){const{ isLoading, data}=useFetchye('http://example.com/api/books/',{initialData:initialBookList,});if(isLoading){return(<p>Loading...</p>);}return({/* Render data */});}constfetchye=makeServerFetchye({  cache,fetchClient:fetch,});exportasyncfunctiongetServerSideProps(){try{// returns { data, error } payload for feeding initialData on client sideconstres=awaitfetchye('http://example.com/api/books/');return{props:{initialBookList:res,},};}catch(error){// eslint-disable-next-line no-console -- error useful to developer in specific error caseconsole.error(error.message);return{};}}

🏖️Try this out on Codesandbox

Write your own Cache

💬 **Note**: This is for advanced users with special cases. Advanced users should understand Redux design pattern concepts aboutReducers andActions before continuing.

Sometimes, the basic opinions of the cache may not be enough for a project's use case. We can create a very basic new Cache configuration like so:

import{IS_LOADING,SET_DATA,DELETE_DATA,ERROR,CLEAR_ERROR,}from'fetchye';exportfunctionCustomCache({ cacheSelector=(state)=>state}){return{// The reducer will save each action to state by hash keyreducer:(state,action)=>{switch(action.type){caseIS_LOADING:{// return is loading state changereturnstate;}caseSET_DATA:{// return set data state changereturnstate;}caseDELETE_DATA:{// return delete data state changereturnstate;}caseERROR:{// return error state changereturnstate;}caseCLEAR_ERROR:{// return clear error state changereturnstate;}default:{returnstate;}}},getCacheByKey:(state,key)=>({      data,// dig into state and return data by key hash value      error,// dig into state and return error by key hash value      loading,// dig into state and return loading by key hash value}),    cacheSelector,// pass through optional cacheSelector property};}

Next we may add this to one of the Fetchye Providers and we are done:

import{FetchyeProvider}from'fetchye';import{CustomCache}from'./CustomCache';constParentComponent=({ children})=>(<FetchyeProvidercache={CustomCache()}>{children}</FetchyeProvider>);

💡 Check outActions API docs andSimpleCache.js source file. These will give you insights into the actions used in the reducer and practical examples on a working Cache configuration.

🎛️ API

Contents

useFetchye

A React Hook used for dispatching asynchronous API requests.

Shape

const { isLoading, data, error, run } = useFetchye(key, { defer: Boolean, mapOptionsToKey: options => options, ...fetchOptions }, fetcher);

Arguments

nametyperequireddescription
keyString or() => StringtrueA string or function returning a string that factors into cache key creation.Defaults to URL compatible string.
optionsObject<Options>falseOptions to pass through to ES6 Fetch. SeeOptions table for the exceptions to this rule. Theoptions object factors into cache key creation.
fetcherasync (fetchClient: Fetch, key: String, options: Options) => ({ payload: Object, error?: Object })falseThe async function that callsfetchClient by key and options. Returns apayload with outcome offetchClient and an optionalerror object.

Options

nametyperequireddescription
mapOptionsToKey(options: Options) => transformedOptionsfalseA function that maps options to the key that will become part of the cache key. See below for a list of mapOptionsToKey helpers.
mapKeyToCacheKey(key: String, options: Options) => cacheKey: StringfalseA function that maps the key for use as the cacheKey allowing direct control of the cacheKey
deferBooleanfalsePrevents execution ofuseFetchye on each render in favor of using the returnedrun function.Defaults tofalse
initialDataObjectfalseSeeds the initial data on first render ofuseFetchye to accomodate server side renderingDefaults toundefined
headersObject or() => ObjectfalseObject: as per the ES6 Compatiblefetch option.() => Object: A function to construct a ES6 Compatibleheaders object prior to any api call
...restOptionsES6FetchOptionstrueContains any ES6 Compatiblefetch option. (SeeFetch Options)

Returns

nametypedescription
isLoadingBooleanA boolean to indicate whether in loading state or not.
dataObjectA result of afetchClient query.Defaults to returning{ status, body, ok, headers } fromfetchClient response
error?ObjectAn object containing an error if present.Defaults to anError object with a thrownfetch error. This is not for API errors (e.g. Status 500 or 400). Seedata for that
runasync () => {}A function for bypassing the cache and firing an API call. This will causeisLoading === true and update the cache based on the result.

makeServerFetchye

A factory function used to generate an async/await fetchye function used for server-side API calls.

Shape

const fetchye = makeServerFetchye({ cache, fetchClient });const { data, error } = await fetchye(key, options, fetcher);

makeServerFetchye Arguments

nametyperequireddescription
cacheCachetrueFetchyeCache object.
fetchClientES6FetchtrueAFetch API compatible function.

fetchye Arguments

nametyperequireddescription
keyString or() => StringtrueA string or function returning a string that factors into cache key creation.Defaults to URL compatible string.
optionsES6FetchOptionsfalseOptions to pass through toES6 Fetch.
fetcherasync (fetchClient: Fetch, key: String, options: Options) => ({ payload: Object, error?: Object })falseThe async function that callsfetchClient by key and options. Returns apayload with outcome offetchClient and an optionalerror object.

fetchye Returns

nametypedescription
dataObjectA result of afetchClient query.Defaults to returning{ status, body, ok, headers } fromfetchClient response
error?ObjectAn object containing an error if present.Defaults to anError object with a thrownfetch error. This is not for API errors (e.g. Status 500 or 400). Seedata for that
runasync () => {}A function for bypassing the cache and firing an API call. Can be awaited.

makeOneServerFetchye

DEPRECATED: You should usedispatch(oneFetchye(key, options, fetcher)) (see docs below) in place ofmakeOneServerFetchye

A factory function used to generate an async/await fetchye function used for making One App server-side API calls.

Shape

const fetchye = makeOneServerFetchye({ store, fetchClient });const { data, error } = await fetchye(key, options, fetcher);

makeOneServerFetchye Arguments

nametyperequireddescription
cacheCachefalseDefaults to OneCache FetchyeCache object.
fetchClientES6FetchtrueAFetch API compatible function.
storeStoretrueARedux Store

fetchye Arguments

nametyperequireddescription
keyString or() => StringtrueA string or function returning a string that factors into cache key creation.Defaults to URL compatible string.
optionsES6FetchOptionsfalseOptions to pass through toES6 Fetch.
fetcherasync (fetchClient: Fetch, key: String, options: Options) => ({ payload: Object, error?: Object })falseThe async function that callsfetchClient by key and options. Returns apayload with outcome offetchClient and an optionalerror object.

fetchye Returns

nametypedescription
dataObjectA result of afetchClient query.Defaults to returning{ status, body, ok, headers } fromfetchClient response
error?ObjectAn object containing an error if present.Defaults to anError object with a thrownfetch error. This is not for API errors (e.g. Status 500 or 400). Seedata for that
runasync () => {}A function for bypassing the cache and firing an API call. Can be awaited.

oneFetchye

Call fetchye in an imperative context, such as in One App's loadModuleData, in a Redux Thunk, or in an useEffect.

Shape

const { data, error } = await dispatch(oneFetchye(key, options, fetcher));

oneFetchye Arguments

nametyperequireddescription
keyString or() => StringtrueA string or function returning a string that factors into cache key creation.Defaults to URL compatible string.
optionsES6FetchOptionsfalseOptions to pass through toES6 Fetch.
fetcherasync (fetchClient: Fetch, key: String, options: Options) => ({ payload: Object, error?: Object })falseThe async function that callsfetchClient by key and options. Returns apayload with outcome offetchClient and an optionalerror object.

onefetchye Returns

A promise resolving to an object with the below keys:

nametypedescription
dataObjectA result of afetchClient query.Defaults to returning{ status, body, ok, headers } fromfetchClient response
error?ObjectAn object containing an error if present.Defaults to anError object with a thrownfetch error. This is not for API errors (e.g. Status 500 or 400). Seedata for that
runasync () => {}A function for bypassing the cache and firing an API call. Can be awaited.

Providers

A Provider creates a React Context to connect all theuseFetchye Hooks into a centrally stored cache.

FetchyeProvider

A React Context Provider that holds the centralized cache for all theuseFetchye React Hooks' query data. This Provider usesuseReducer for cache storage.

Shape

<FetchyeProvider cache={SimpleCache()}>  {children}</FetchyeProvider>

Props

nametyperequireddescription
fetchClientES6FetchtrueAFetch API compatible function.
cacheCachefalseFetchyeCache object.Defaults toSimpleCache
initialDataObjectfalseInitial state to feed into Cache Configurationreducer

FetchyeReduxProvider

💡Requires additionalredux andreact-redux packages installed

A React Context Provider that uses Redux to store the centralized cache for all theuseFetchye React Hooks' query data.

Shape

import { FetchyeReduxProvider } from "fetchye-redux-provider";
<Provider>  <FetchyeReduxProvider cache={SimpleCache()}>    {children}  </FetchyeReduxProvider></Provider>

Context

nametyperequireddescription
ReactReduxContextReactReduxContexttrueARedux Context from a<Provider />.

Props

nametyperequireddescription
fetchClientES6FetchtrueAFetch API compatible function.
cacheCachefalseFetchyeCache object.Defaults toSimpleCache

OneFetchyeProvider

💡Requires additionalredux andreact-redux packages installed

A Context Provider that is specifically designed for use with One App.

Shape

import{OneFetchyeProvider}from'fetchye-one-app';
<Provider><OneFetchyeProvider>{children}</OneFetchyeProvider></Provider>;

Context

nametyperequireddescription
ReactReduxContextReactReduxContexttrueARedux Context from a<Provider />.

Props

nametyperequireddescription
fetchClientES6FetchtrueAFetch API compatible function.
cacheCachefalseFetchyeCache object.Defaults toOneCache

Caches

A factory function that returns a configuration object, used to instruct a Provider on how to store and retrieve fetchye cache data.

SimpleCache

This Cache configuration relies on plain old Javascript data structures to back thereducer andgetCacheByKey functions.

Shape

import { SimpleCache } from 'fetchye';const cache = SimpleCache({  cacheSelector,});

Arguments

nametyperequireddescription
cacheSelector(state) => statefalseRequired if usingFetchyeReduxProvider A function that returns the location inside Redux State to the Fetchye Cache. (SeeRedux Selectors).

Returns

nametypedescription
reducer(state, action) => stateA function that reduces the next state of Fetchye Cache. (SeeRedux Reducers).
getCacheByKey(cache, key) => stateA function that returns a minimum of{ data, loading, error } for a specific cache key from cache state.
cacheSelector?(state) => stateAn optionally returned parameter. This function returns the location inside Redux State to the Fetchye Cache. (SeeRedux Selectors).

ImmutableCache

💡Requires additionalimmutable package installed

This Cache configuration relies on ImmutableJS data structures to back thereducer andgetCacheByKey functions.

Shape

import { ImmutableCache } from 'fetchye-immutable-cache';const cache = ImmutableCache({  cacheSelector});

Arguments

nametyperequireddescription
cacheSelector(state) => statefalseRequired if usingFetchyeReduxProvider A function that returns the location inside Redux State to the Fetchye Cache. (SeeRedux Selectors).

Returns

nametypedescription
reducer(state, action) => stateA function that reduces the next state of Fetchye Cache. (SeeRedux Reducers).
getCacheByKey(cache = Immutable.Map(), key) => stateA function that returns a minimum of{ data, loading, error } for a specific cache key from cache state.
cacheSelector?(state) => stateAn optionally returned parameter. This function returns the location inside Redux State to the Fetchye Cache. (SeeRedux Selectors).

OneCache

💡Requires additionalimmutable package installed

This Cache configuration is specifically designed to work with One App, it relies on ImmutableJS data structures to back thereducer andgetCacheByKey functions.

Shape

import { OneCache } from 'fetchye-one-app';const cache = OneCache();

Returns

nametypedescription
reducer(state, action) => stateA function that reduces the next state of Fetchye Cache. (SeeRedux Reducers).
getCacheByKey(cache = Immutable.Map(), key) => stateA function that returns a minimum of{ data, loading, error } for a specific cache key from cache state.
cacheSelector?(state) => stateAn optionally returned parameter. This function returns the location inside Redux State to the Fetchye Cache. (SeeRedux Selectors).

Actions

These actions power the state transitions described in a Cache Configurationreducer function.

IS_LOADING

An event signaling a state transition to the loading state by hash key.

Shape

import { IS_LOADING } from 'fetchye-core';
{  type: IS_LOADING,  hash,}

Child Properties

nametypedescription
hashStringThe hash value generated byobject-hash package for the query

SET_DATA

An event signaling a state transition inside a reducer to add or replace the data field and transition away from loading state by hash key.

Shape

import { SET_DATA } from 'fetchye-core';
{  type: SET_DATA,  hash,  value,}

Child Properties

nametypedescription
hashStringThe hash value generated byobject-hash package for the query
valueObjectContains thepayload data returned from thefetcher insideuseFetchye

DELETE_DATA

An event signaling a state transition inside a reducer to remove the data field by hash key.

Shape

import { DELETE_DATA } from 'fetchye-core';
{  type: DELETE_DATA,  hash,}

Child Properties

nametypedescription
hashStringThe hash value generated byobject-hash package for the query

ERROR

An event signaling a state transition inside a reducer to insert an error and transition away from loading state by hash key.

Shape

import { ERROR } from 'fetchye-core';
{  type: ERROR,  hash,  error,}

Child Properties

nametypedescription
hashStringThe hash value generated byobject-hash package for the query
error`ErrorString

CLEAR_ERROR

An event signaling a state transition inside a reducer to remove an error by hash key.

Shape

import { CLEAR_ERROR } from 'fetchye-core';
{  type: CLEAR_ERROR,  hash,}

Child Properties

nametypedescription
hashStringThe hash value generated byobject-hash package for the query

mapOptionToKey Helpers

These helpers provide a more compact and simple way of common transforms.

There is currently one helper.

ignoreHeadersByKey

Shape

(String[]) => mapOptionsToKeyFunction

Arguments

nametyperequireddescription
keysArray<String>truecreates a mapOptionsToKey function that removes headers whose keys match the specified keys

Returns

nametypedescription
mapOptionsToKey FunctionmapOptionsToKeyFunctionA function to be passed to the mapOptionsToKey option in useFetchye, or thefetchye function made bymakeServerFetchye.

Example

importReactfrom'react';import{useFetchye,ignoreHeadersByKey}from'fetchye';constBookList=({ locale})=>{const{ isLoading, data}=useFetchye('http://example.com/api/books/',{// remove the 'locale' header from the headers when building the cache keymapOptionsToKey:ignoreHeadersByKey(['locale']),headers:{ locale},});// ... rest of component};exportdefaultBookList;

📢 Mission

The Fetchye project wishes to bring a more flexible central caching experience using the best ideas of the Redux design pattern and options for the developer to choose how their data is stored. Fetchye provides React Context driven caching options backed by your choice of pure React (viauseReducer) or Redux. Unlike many data fetching solutions, Fetchye Context Providers do not rely on singleton statics and can be instantiated throughout an application multiple times for multiple caches if so desired.

🏆 Contributing

We welcome Your interest in the American Express Open Source Community on Github. Any Contributor to any Open Source Project managed by the American Express Open Source Community must accept and sign an Agreement indicating agreement to the terms below. Except for the rights granted in this Agreement to American Express and to recipients of software distributed by American Express, You reserve all right, title, and interest, if any, in and to Your Contributions. Pleasefill out the Agreement.

Please feel free to open pull requests and seeCONTRIBUTING.md to learn how to get started contributing.

🗝️ License

Any contributions made under this project will be governed by theApache License 2.0.

🗣️ Code of Conduct

This project adheres to theAmerican Express Community Guidelines. By participating, you are expected to honor these guidelines.

About

✨ If you know how to use Fetch, you know how to use Fetchye [fetch-yae]. Simple React Hooks, Centralized Cache, Infinitely Extensible.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp