Optimize swr data mutation

This commit is contained in:
Sam Becker 2024-04-25 23:21:02 -05:00
parent 61839e66c8
commit ebf1976203
4 changed files with 26 additions and 24 deletions

View File

@ -10,7 +10,7 @@ import { usePathname } from 'next/navigation';
import { BiTrash } from 'react-icons/bi';
import MoreMenu from '@/components/MoreMenu';
import { useAppState } from '@/state/AppState';
import { RevalidatePhotos } from '@/photo/InfinitePhotoScroll';
import { RevalidatePhoto } from '@/photo/InfinitePhotoScroll';
export default function AdminPhotoMenuClient({
photo,
@ -18,7 +18,7 @@ export default function AdminPhotoMenuClient({
...props
}: Omit<ComponentProps<typeof MoreMenu>, 'items'> & {
photo: Photo
revalidatePhoto?: RevalidatePhotos
revalidatePhoto?: RevalidatePhoto
}) {
const { isUserSignedIn } = useAppState();
@ -49,7 +49,7 @@ export default function AdminPhotoMenuClient({
action: () => toggleFavoritePhotoAction(
photo.id,
shouldRedirectFav,
).then(() => revalidatePhoto?.()),
).then(() => revalidatePhoto?.(photo.id)),
}, {
label: 'Delete',
icon: <BiTrash
@ -62,7 +62,7 @@ export default function AdminPhotoMenuClient({
photo.id,
photo.url,
shouldRedirectDelete,
).then(() => revalidatePhoto?.(true));
).then(() => revalidatePhoto?.(photo.id, true));
}
},
},

View File

@ -10,7 +10,8 @@ import { getPhotosAction } from '@/photo/actions';
import { useAppState } from '@/state/AppState';
import { Photo } from '.';
export type RevalidatePhotos = (
export type RevalidatePhoto = (
photoId: string,
revalidateRemainingPhotos?: boolean,
) => Promise<any>;
@ -80,21 +81,22 @@ export default function InfinitePhotoScroll({
}
}, [triggerOnView, advance]);
const photos = useMemo(() => (data ?? [])?.flat(), [data]);
const revalidatePhoto: RevalidatePhoto = useCallback((
photoId: string,
revalidateRemainingPhotos?: boolean,
) => mutate(data, {
revalidate: (_data: Photo[], [_, size]:[string, number]) => {
const i = (data ?? []).findIndex(photos =>
photos.some(photo => photo.id === photoId));
return revalidateRemainingPhotos ? size >= i : size === i;
},
} as any), [data, mutate]);
return (
<div className="space-y-4">
{data && <div className="space-y-1">
{data.map((photos, i) =>
<PhotosLarge
key={i}
photos={photos}
revalidatePhotos={(revalidateRemainingPhotos?: boolean) =>
mutate(data, {
revalidate: (_data: any, [_, size]:[string, number]) =>
revalidateRemainingPhotos ? size >= i : size === i,
} as any)
}
/>)}
</div>}
<PhotosLarge {...{ photos, revalidatePhoto }} />
{!isFinished &&
<SiteGrid
contentMain={

View File

@ -21,7 +21,7 @@ import DivDebugBaselineGrid from '@/components/DivDebugBaselineGrid';
import PhotoLink from './PhotoLink';
import { SHOULD_PREFETCH_ALL_LINKS } from '@/site/config';
import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient';
import { RevalidatePhotos } from './InfinitePhotoScroll';
import { RevalidatePhoto } from './InfinitePhotoScroll';
export default function PhotoLarge({
photo,
@ -42,7 +42,7 @@ export default function PhotoLarge({
priority?: boolean
prefetch?: boolean
prefetchRelatedLinks?: boolean
revalidatePhoto?: RevalidatePhotos
revalidatePhoto?: RevalidatePhoto
showCamera?: boolean
showSimulation?: boolean
shouldShareTag?: boolean

View File

@ -1,18 +1,18 @@
import AnimateItems from '@/components/AnimateItems';
import { Photo } from '.';
import PhotoLarge from './PhotoLarge';
import { RevalidatePhotos } from './InfinitePhotoScroll';
import { RevalidatePhoto } from './InfinitePhotoScroll';
export default function PhotosLarge({
photos,
animate = true,
prefetchFirstPhotoLinks,
revalidatePhotos,
revalidatePhoto,
}: {
photos: Photo[]
animate?: boolean
prefetchFirstPhotoLinks?: boolean
revalidatePhotos?: RevalidatePhotos
revalidatePhoto?: RevalidatePhoto
}) {
return (
<AnimateItems
@ -28,7 +28,7 @@ export default function PhotosLarge({
photo={photo}
priority={index <= 1}
prefetchRelatedLinks={prefetchFirstPhotoLinks && index === 0}
revalidatePhoto={revalidatePhotos}
revalidatePhoto={revalidatePhoto}
/>)}
itemKeys={photos.map(photo => photo.id)}
/>