#Submit in useFetcher ignores deferred value thats returned from loader

1 messages · Page 1 of 1 (latest)

thin heron
#

this is the pagination hook ( pagination provided by mantine ):

export function usePagination<T>(count: number) {

    const [searchParams, setSearchParams] = useSearchParams();
    const { state } = useRevalidator();
    const fetcher = useFetcher();

    const onChangePagination = useCallback((value: number) => {

        fetcher.submit(
            { page: value.toString() },
            { method: "get" }
        );

    }, [fetcher]);

    const render = (
        <fetcher.Form
            method="get"
        >
            <Pagination
                defaultValue={parseInt(searchParams.get('page') ?? "1")}
                total={count}
                onChange={onChangePagination}
                disabled={fetcher.state === "loading" || state === "loading"}
            />
        </fetcher.Form>
    );

    return { render };
}```
#

this is the page:

const SandboxPage = () => {

    const loader = useLoaderData() as { count: number; promise: Promise<number>; };
    const pagination = usePagination(loader.count);

    return (
        <>
            {pagination.render}

            <SuspenseAwait
                resolve={loader.promise}
                fallback={<Button>Loading...</Button>}
            >
                {(data) => (
                    <Button>{data}</Button>
                )}
            </SuspenseAwait>
        </>
    );
};

SandboxPage.loader = async ({ params, request, context }: LoaderFunctionArgs) => {

    const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min);

    const latePromise = (async () => {
        await sleep(random(3000, 5000));
        return random(100, 200);
    })();

    return defer({
        count: random(100, 200),
        promise: latePromise
    });
};
#

SuspenseAwait:

export type SuspenseAwaitProps<T> = {
    resolve: Promise<T>;
    children: ReactNode | ((data: Awaited<T>) => ReactNode);
    errorElement?: ReactNode;
    fallback?: ReactNode;
};

export function SuspenseAwait<T>(props: SuspenseAwaitProps<T>) {

    return (
        <Suspense fallback={props.fallback}>
            <Await
                errorElement={props.errorElement}
                resolve={props.resolve}
            >
                {props.children}
            </Await>
        </Suspense>
    );
}```
#

first run:

#

when the loader is loading after pagination has been changed: