Server Action on client-component
Answered
Noronha posted this in #help-forum
NoronhaOP
I'm using a server actions to fetch data from the backend from a client-component (Datatable).
Since I cant call the async server action from the client-component, my datatable changes the url params like:
And then the page reloads and passes down the new data. It works great.
So then I was designing the page's skeleton. I put a 3sec delay to help design it.
No problem so far but when I clicked to change page (for example), the URL changes but there's no indication for the users that something is loading.
The page just changes when its done.
I have a video showcasing that here: https://we.tl/t-93kqolB5Fv
Any idea how can I improve the feedback to the user in those cases?
Is there a better way to do it (with server actions, I really dont want to use fetch and api endpoints) without changing the URL?
PS: I'm new to react/next. Its my first project, but I'm loving it!
Thank you guys
Since I cant call the async server action from the client-component, my datatable changes the url params like:
?page=1&q=andr&sortField=driverName&sortDirection=asc And then the page reloads and passes down the new data. It works great.
So then I was designing the page's skeleton. I put a 3sec delay to help design it.
No problem so far but when I clicked to change page (for example), the URL changes but there's no indication for the users that something is loading.
The page just changes when its done.
I have a video showcasing that here: https://we.tl/t-93kqolB5Fv
Any idea how can I improve the feedback to the user in those cases?
Is there a better way to do it (with server actions, I really dont want to use fetch and api endpoints) without changing the URL?
PS: I'm new to react/next. Its my first project, but I'm loving it!
Thank you guys
24 Replies
try using it with
useTransition hookconst [isPending, startTransition] = useTransition()
const router = useRouter()
const changeUrl = () => {
startTransition(() => {
router.push()
})
}NoronhaOP
I'm using replace:
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
const searchParams = useSearchParams()
const { replace } = useRouter()
const pathname = usePathname()
params.set('page', newPage.toString())
replace(`${pathname}?${params}`)NoronhaOP
Cool, thank you my friend. I'll try that ASAP
Answer
NoronhaOP
I think I did something wrong, but when I added the transition I'm now getting:
Error: Text content does not match server-rendered HTML.
Warning: Text content did not match. Server: "13/01/2024, 21:44" Client: "13/01/2024 21:44"
See more info here: https://nextjs.org/docs/messages/react-hydration-error
I just added the hook and called before replace:
Error: Text content does not match server-rendered HTML.
Warning: Text content did not match. Server: "13/01/2024, 21:44" Client: "13/01/2024 21:44"
See more info here: https://nextjs.org/docs/messages/react-hydration-error
I just added the hook and called before replace:
const [isPending, startTransition] = useTransition()
startTransition(() => {
replace(`${pathname}?${params}`)
})
// and disabled the button
<Button
onClick={() => handleClick('prev')}
disabled={!hasPrev || isPending}
> startTransition(() => {
replace(`${pathname}?${params}`)
})is this inside handleClick?
@Noronha I think I did something wrong, but when I added the transition I'm now getting:
Error: Text content does not match server-rendered HTML.
Warning: Text content did not match. Server: "13/01/2024, 21:44" Client: "13/01/2024 21:44"
See more info here: https://nextjs.org/docs/messages/react-hydration-error
I just added the hook and called before replace:
const [isPending, startTransition] = useTransition()
startTransition(() => {
replace(`${pathname}?${params}`)
})
// and disabled the button
<Button
onClick={() => handleClick('prev')}
disabled={!hasPrev || isPending}
>
you should not write code directly inside your component it should be inside a
useEffect or some callback funtion@Ray ts
startTransition(() => {
replace(`${pathname}?${params}`)
})
is this inside handleClick?
NoronhaOP
Yes:
const handleClick = (type: 'prev' | 'next') => {
const params = new URLSearchParams(searchParams)
const newPage = type === 'prev' ? page - 1 : page + 1
params.set('page', newPage.toString())
startTransition(() => {
replace(`${pathname}?${params}`)
})
}I use that function like:
onClick={() => handleClick('prev')}NoronhaOP
Yes, it still works even with the error messages
yes the error should be come from somewhere
where do you render the date 13/01/2024, 21:44"
NoronhaOP
Inside the table I have a FormatDate:
export default function FormatDate ({ date }: { date: string }) {
return (
<span>
{new Date(date).toLocaleString('pt-BR', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZone: 'America/Sao_Paulo'
})}
</span>
)
}@Noronha Inside the table I have a FormatDate:
export default function FormatDate ({ date }: { date: string }) {
return (
<span>
{new Date(date).toLocaleString('pt-BR', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZone: 'America/Sao_Paulo'
})}
</span>
)
}
this is going to cause hydration warning, since the server and the client may not be in the same timezone
try to pass
suppressHydrationWarning to the <span />NoronhaOP
aaaaaaah, yeah that worked
Thank you Ray, you're awesome. Should we fix t his hydration error in some other way, or its ok just to suppress the warning?
I think it is ok
this is a warning not error actually
NoronhaOP
Thank you again, couldn't do it without you! â¤ï¸
you're welcome