December 30, 2021
Letās say you want to refresh the data on a page of your Remix app on a defined interval, like every 30 seconds.
One solution would be to use the navigate
function to ānavigateā to the current page, like this: navigate(".", { replace: true })
. However, this also causes the pageās scroll position to jump to the top, which often isnāt what we want.
Instead, we can use Remixās useFetcher
hook.
Hereās the code, and Iāll explain it afterwards:
// app/routes/my-page.jsx
import { useState, useEffect } from "react";
import { useLoaderData, useFetcher } from "remix";
export default function () {
const loaderData = useLoaderData();
const [data, setData] = useState(loaderData);
// Whenever the loader gives us new data
// (for example, after a form submission),
// update our `data` state.
useEffect(() => setData(loaderData), [loaderData]);
const fetcher = useFetcher();
// Get fresh data every 30 seconds.
useEffect(() => {
const interval = setInterval(() => {
if (document.visibilityState === "visible") {
fetcher.load("/my-page");
}
}, 30 * 1000);
return () => clearInterval(interval);
}, []);
// When the fetcher comes back with new data,
// update our `data` state.
useEffect(() => {
if (fetcher.data) {
setData(fetcher.data);
}
}, [fetcher.data]);
return (
// Construct JSX view here, using `data`.
);
}
useLoaderData
, weāre using a piece of state called data
and keeping data
up-to-date with the loader data. This way, we can also update data
when we fetch new data every 30 seconds.useEffect
. Therefore, weāre returning a function that cleans up our interval, so this doesnāt keep polling every 30 seconds even after the user goes to another page.fetcher.data
will be updated. In reaction to this, we use another useEffect
to update our data
state whenever the fetcher returns new data.useEffect
will run once when the page is mounted as well, when the fetcher hasnāt fetched any data for us. Therefore, we need to make sure fetcher.data
actually has data before using it.Thatās it! Now, the data for this route will be re-fetched every 30 seconds (or however often youād like), without refreshing the entire page.
Tufts Meal Plan Wrapped
Mar 2, 2024
Building an e-ink picture frame that displays an iCloud photo album
Jan 9, 2024
2023 in review
Jan 5, 2024
Subscribe to my newsletter for a monthly round-up of new blog posts and projects Iām working on!