Demo code from Refresh React Server Components. Watch on YouTube.
page.tsx
A React Server Component that lives in app/posts/[postId]/page.tsx
.
import { RefreshCache } from "./refresh-cache";
export default async function PostPage({
params,
}: {
params: { postId: string };
}) {
const post = await getPost(params.postId);
const postLastUpdated = post.updatedAt.getTime();
async function checkIfPostChanged() {
"use server";
const checkPost = await getPost(params.postId);
const checkPostLastUpdated = checkPost.updatedAt.getTime();
const didChange = postLastUpdated !== checkPostLastUpdated;
if (didChange) {
revalidatePath("/");
}
}
return (
<div>
{/* ... */}
<RefreshCache check={checkIfPostChanged} />
</div>
);
}
refresh-cache.tsx
"use client";
import { useInterval } from "interval-hooks";
import { useEffect, useState } from "react";
export function RefreshCache({ check }: { check: () => Promise<void> }) {
const [shouldRun, setShouldRun] = useState(
typeof document !== "undefined" && document.hasFocus()
);
useEffect(() => {
const onFocus = () => {
check();
setShouldRun(true);
};
const onBlur = () => setShouldRun(false);
window.addEventListener("focus", onFocus);
window.addEventListener("blur", onBlur);
return () => {
window.removeEventListener("focus", onFocus);
window.removeEventListener("blur", onBlur);
};
}, [check]);
useInterval(check, shouldRun ? 1000 : null);
return null;
}