-
Notifications
You must be signed in to change notification settings - Fork 27
Open
Description
I was playing around with my own progress bar implementation while referencing this library, and I discovered that you don't actually have to call startProgress in the same callback with the task you're trying to track:
"use client";
import NextLink from "next/link";
import {
type ComponentPropsWithoutRef,
forwardRef,
startTransition,
} from "react";
import { useProgress } from "react-transition-progress";
export const Link = forwardRef<
HTMLAnchorElement,
ComponentPropsWithoutRef<typeof NextLink>
>(({ onClick, ...props }, ref) => {
const startProgress = useProgress();
return (
<NextLink
ref={ref}
onClick={(e) => {
onClick?.(e);
startTransition(startProgress);
}}
{...props}
/>
);
});
Link.displayName = "Link";I have no idea why this even works though. I tested it with heavy network throttling and everything seems perfectly sound.
If this is actually a good approach, it would eliminate the need to duplicate Link's logic (like the current URL formatter).
Would appreciate more eyes on this though (and maybe an explanation too).
EDIT: Also works for submit buttons in server action forms:
button.tsx
"use client";
export const Button = forwardRef<
HTMLButtonElement,
ComponentPropsWithoutRef<"button">
>(({ onClick, ...props }, ref) => {
const startProgress = useProgress();
return (
<button
ref={ref}
onClick={(e) => {
onClick?.(e);
startTransition(startProgress);
}}
{...props}
/>
);
});
Button.displayName = "Button";page.tsx
export default function Page() {
return (
<form
action={async () => {
"use server";
// Play with the timeout value below to test if progress bar is accurate
await new Promise((r) => setTimeout(r, 7000));
}}
>
<Button type="submit">Submit!</Button>
</form>
);
}eug-vs
Metadata
Metadata
Assignees
Labels
No labels