Skip to content

Commit

Permalink
feat: mutate additional cache keys in useFetch
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Jul 26, 2023
1 parent 67757c1 commit e9d9d6a
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 31 deletions.
13 changes: 7 additions & 6 deletions packages/core/src/data/strategies/AbstractFetchStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,20 +329,21 @@ export abstract class AbstractFetchStrategy<E, Params extends EndpointParams, R
}

/**
* Returns the cache key
* Returns the cache key with both the endpoint and the sourceUrl to distinguish between multiple sites
*
* @param params
* @returns
* @param params The request params
*
* @returns The cache key object
*/
getCacheKey(params: Partial<Params>) {
return { url: this.getDefaultEndpoint(), args: { ...params, sourceUrl: this.baseURL } };
}

/**
* Normalize data for cache
* Normalize data for cache.
*
* @param data
* @param params
* @param data The fetch response data
* @param params The request params
*/
normalizeForCache(
data: FetchResponse<R>,
Expand Down
12 changes: 4 additions & 8 deletions packages/core/src/data/strategies/PostOrPostsFetchStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class PostOrPostsFetchStrategy<
try {
const results = await this.postStrategy.fetcher(
singleURL,
params.single ?? {},
singleParams,
options,
);

Expand All @@ -182,7 +182,7 @@ export class PostOrPostsFetchStrategy<
try {
const results = await this.postsStrategy.fetcher(
archiveURL,
params.archive ?? {},
archiveParams,
options,
);

Expand Down Expand Up @@ -211,7 +211,7 @@ export class PostOrPostsFetchStrategy<
try {
const results = await this.postsStrategy.fetcher(
archiveURL,
params.archive ?? {},
archiveParams,
options,
);

Expand All @@ -230,11 +230,7 @@ export class PostOrPostsFetchStrategy<

if (shouldFetchSingle) {
try {
const results = await this.postStrategy.fetcher(
singleURL,
params.single ?? {},
options,
);
const results = await this.postStrategy.fetcher(singleURL, singleParams, options);

return {
...results,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/react/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface HookResponse {
export interface FetchHookOptions<T> {
fetchStrategyOptions?: Partial<FetchOptions>;
swr?: SWRConfiguration<T>;
shouldFetch?: boolean;
}
29 changes: 25 additions & 4 deletions packages/core/src/react/hooks/useFetch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import useSWR from 'swr';
import useSWR, { useSWRConfig } from 'swr';
import deepmerge from 'deepmerge';
import type { EndpointParams, FetchResponse } from '../../data';
import { AbstractFetchStrategy } from '../../data';
Expand Down Expand Up @@ -31,6 +31,7 @@ export function useFetch<E, Params extends EndpointParams, R = E>(
path = '',
) {
const { sourceUrl, debug } = useSettings();
const { mutate } = useSWRConfig();

fetchStrategy.setBaseURL(sourceUrl);

Expand All @@ -40,7 +41,7 @@ export function useFetch<E, Params extends EndpointParams, R = E>(

const finalParams = deepmerge.all([defaultParams, urlParams, params]) as Partial<Params>;

const { fetchStrategyOptions, ...validSWROptions } = options;
const { fetchStrategyOptions, shouldFetch = true, ...validSWROptions } = options;

// for backwards compat ensure options.swr exists
// this would make code that's not namespacing the swr options under `{ swr }` still work.
Expand All @@ -63,8 +64,28 @@ export function useFetch<E, Params extends EndpointParams, R = E>(
}

const result = useSWR<FetchResponse<R>>(
key,
() => fetchStrategy.fetcher(endpointUrl, finalParams, fetchStrategyOptions),
shouldFetch ? key : null,
async () => {
const fetchData = await fetchStrategy.fetcher(
endpointUrl,
finalParams,
fetchStrategyOptions,
);

const { data, additionalCacheObjects } = fetchStrategy.normalizeForCache(
fetchData,
finalParams,
);

// mutate additiional cache objects
if (additionalCacheObjects) {
additionalCacheObjects.forEach(({ key, data }) => {
mutate(key, data);
});
}

return data;
},
options.swr,
);

Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/react/hooks/useFetchPostOrPosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,20 @@ export function useFetchPostOrPosts<
path,
);

// TODO: should fetch
const { data: postData } = useFetchPost<T>(params.single, undefined, path);
const { data: postsData } = useFetchPosts<T>(params.archive, undefined, path);
const { data: postData } = useFetchPost<T>(
params.single,
{
shouldFetch: data?.result.isSingle ?? false,
},
path,
);
const { data: postsData } = useFetchPosts<T>(
params.archive,
{
shouldFetch: data?.result.isArchive ?? false,
},
path,
);

if (error || !data) {
const fakeData = {
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/data/hooks/usePostOrPosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FetchHookOptions, useFetchPostOrPosts } from '@headstartwp/core/react';
import { usePrepareFetch } from './usePrepareFetch';

/**
* The usePostOrPosts hook
*
* @param params The parameters accepted by the hook
* @param options Options for the SWR configuration
Expand Down
8 changes: 1 addition & 7 deletions packages/next/src/data/server/fetchHookData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export async function fetchHookData<T = unknown, P extends EndpointParams = Endp
additionalCacheObjects = normalizedData.additionalCacheObjects.map((cacheObject) => ({
...cacheObject,
key: serializeKey(cacheObject.key),
isMainQuerty: fetchStrategy.isMainQuery(stringPath, params),
isMainQuery: fetchStrategy.isMainQuery(stringPath, params),
}));
}

Expand All @@ -162,10 +162,4 @@ export async function fetchHookData<T = unknown, P extends EndpointParams = Endp
isMainQuery: fetchStrategy.isMainQuery(stringPath, params),
additionalCacheObjects: additionalCacheObjects || null,
};

/* return {
key: serializeKey(key),
data: fetchStrategy.filterData(data, options.filterData as unknown as FilterDataOptions<R>),
isMainQuery: fetchStrategy.isMainQuery(stringPath, params),
}; */
}
6 changes: 5 additions & 1 deletion projects/wp-nextjs/src/components/PageContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ const Blocks = dynamic(() => import('./Blocks'));
export const PageContent = ({ params }) => {
// This won't require a refetch as long as the data has already been fetched at the page level.
// additionally, if the request has not been SSR'd, it will be fetched on the client only once, regardless of how many call to usePost (with the same params) you make
const { data } = usePost(params);
const { data, loading } = usePost(params);

if (loading) {
return 'loading';
}

return (
<>
Expand Down
12 changes: 10 additions & 2 deletions projects/wp-nextjs/src/pages/blog/[[...path]].js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import { resolveBatch } from '../../utils/promises';
import { PageContent } from '../../components/PageContent';

const Archive = () => {
const { data } = usePosts(blogParams.archive);
const { data, loading } = usePosts(blogParams.archive);

if (loading) {
return 'loading usePosts';
}

return (
<>
Expand All @@ -39,7 +43,11 @@ const Archive = () => {
};

const BlogPage = () => {
const { isArchive } = usePostOrPosts(blogParams);
const { isArchive, loading } = usePostOrPosts(blogParams);

if (loading) {
return 'Loading usePostOrPosts';
}

if (isArchive) {
return <Archive />;
Expand Down

0 comments on commit e9d9d6a

Please sign in to comment.