How to refresh data periodically without reloading the page?
Answered
Blue swimming crab posted this in #help-forum
Blue swimming crabOP
Hi everyone, this might sound like a basic question but I'm not sure how to solve it best:
I'm using Next.js 13 with the app dir and am fetching data with Prisma in a few server components.
I'd like to refresh those server components every few seconds so the user doesn't have to refresh the page to get updated data.
What's the best way to do this?
I'm using Next.js 13 with the app dir and am fetching data with Prisma in a few server components.
I'd like to refresh those server components every few seconds so the user doesn't have to refresh the page to get updated data.
What's the best way to do this?
Answered by Blue swimming crab
I solved it now with server actions: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
The component is a client component now:
It works, could probably use some optimization though 😄 An advantage over
The component is a client component now:
'use client'
import { FC } from 'react'
import { DataTile } from '../data-tile'
import { useInterval } from '../use-interval'
import { getActiveRaids } from './get-active-raids'
export const ActiveRaids: FC = () => {
const activeRaidCount = useInterval(getActiveRaids, 60_000)
return <DataTile iconSrc='/raid.png' metric={activeRaidCount} metricUnit='Raids' secondLine='ready for battle' />
}
useInterval()
is a small hook that calls the given method periodically and returns the result.getActiveRaids
is a server action now:'use server'
import { prisma } from '@/utils/prisma'
export const getActiveRaids = () =>
prisma.gym.count({
where: { raid_end_timestamp: { gte: Math.floor(Date.now() / 1000) } },
})
It works, could probably use some optimization though 😄 An advantage over
router.refresh()
might be that I don't have to refresh all server components at once as I have different intervals for each "data tile".7 Replies
American Shorthair
@Blue swimming crab try to use hooks like useState and useEffect in order to check variable state and refresh content with useEffect providing const as dependency
Blue swimming crabOP
@American Shorthair So in a client component then? How would I refresh a server component from there?
American Shorthair
@Blue swimming crab could you show your components for better understanding?
Blue swimming crabOP
One component here for example:
I'm then using it in a
The
import { cache, FC } from 'react'
import { prisma } from '@/utils/prisma'
import { DataTile } from './data-tile'
export const ActiveRaids: FC = async () => {
const activeRaidCount = await cache(
async () =>
await prisma.gym.count({
where: { raid_end_timestamp: { gte: Math.floor(Date.now() / 1000) } },
}),
)()
return <DataTile iconSrc='/raid.png' metric={activeRaidCount} metricUnit='Raids' secondLine='ready for battle' />
}
I'm then using it in a
page.tsx
page file.The
DataTile
component just formats the data in a pretty way, nothing special in there.Barbary Lion
Interested in this as well
I haven't tried this yet myself, but if I'm reading the docs correctly, you can do this using
It should refresh server components and call your prisma function again. I'm not sure how this works with the
router.refresh()
from the client side, see docs here: https://nextjs.org/docs/app/api-reference/functions/use-router#userouterIt should refresh server components and call your prisma function again. I'm not sure how this works with the
cache
function you're using thoughBlue swimming crabOP
I solved it now with server actions: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
The component is a client component now:
It works, could probably use some optimization though 😄 An advantage over
The component is a client component now:
'use client'
import { FC } from 'react'
import { DataTile } from '../data-tile'
import { useInterval } from '../use-interval'
import { getActiveRaids } from './get-active-raids'
export const ActiveRaids: FC = () => {
const activeRaidCount = useInterval(getActiveRaids, 60_000)
return <DataTile iconSrc='/raid.png' metric={activeRaidCount} metricUnit='Raids' secondLine='ready for battle' />
}
useInterval()
is a small hook that calls the given method periodically and returns the result.getActiveRaids
is a server action now:'use server'
import { prisma } from '@/utils/prisma'
export const getActiveRaids = () =>
prisma.gym.count({
where: { raid_end_timestamp: { gte: Math.floor(Date.now() / 1000) } },
})
It works, could probably use some optimization though 😄 An advantage over
router.refresh()
might be that I don't have to refresh all server components at once as I have different intervals for each "data tile".Answer