Skip to content

Instantly share code, notes, and snippets.

@lunelson
Last active May 15, 2021 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunelson/6d284c08431c017c7e97c165b6b20465 to your computer and use it in GitHub Desktop.
Save lunelson/6d284c08431c017c7e97c165b6b20465 to your computer and use it in GitHub Desktop.
Refresh Next.js server/static props on DatoCMS update
import { useEffect, useRef, useState } from 'react';
import { subscribeToQuery } from 'datocms-listen';
import { useRouter } from 'next/router';
import { reporter } from '../utils';
/*
references for this technique of using router.replace
- https://www.joshwcomeau.com/nextjs/refreshing-server-side-props/
- https://twitter.com/flybayer/status/1333081016995622914
- https://medium.com/wearewebera/updating-the-properties-of-the-getstaticprops-method-in-next-js-79a17b7801e1
questions
- how can I return something useful from this, so I know if we are in a "loading" state?
- how can I prevent an additional run when the page first mounts?
*/
export function useDatoListeners(...queries) {
const router = useRouter();
const unsubsRef = useRef(queries);
const [isUpdating, setIsUpdating] = useState(false);
// const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const { info, table } = reporter();
if (router.isPreview) {
// setTimeout(() => setIsLoading(false), 1000);
unsubsRef.current = unsubsRef.current.map((query) =>
subscribeToQuery({
...query,
// preview: router.isPreview,
// token: process.env.DATOCMS_TOKEN,
onChannelError({ code, message, response }) {
table({ code, message, response });
window.location.reload(true); // retry the connection !
},
onUpdate() {
if (isUpdating) return;
info('datocms update received');
// shallow: false causes getStaticProps to run; scroll: false maintains position
router.replace(router.asPath, router.asPath, { shallow: false, scroll: false });
setTimeout(() => setIsUpdating(false), 1000);
},
}),
);
return () => Promise.all(unsubsRef.current).then((unsubs) => unsubs.forEach((unsub) => unsub()));
}
}, []);
return isUpdating;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment