remix icon indicating copy to clipboard operation
remix copied to clipboard

Page scrolled back to the top when redirecting to same the page from useFetcher Form

Open MattKintonCinch opened this issue 3 years ago • 7 comments

What version of Remix are you using?

1.4.1

Steps to Reproduce

Submit a form from useFetcher

import type { ActionFunction } from '@remix-run/node';
import { redirect } from '@remix-run/node';
import { useFetcher } from '@remix-run/react';

export const action: ActionFunction = () => {
    return redirect('/test');
};

export default function Test() {
    const fetcher = useFetcher();

    return (
        <div>
            <fetcher.Form method="post" style={{ marginTop: '150vh' }}>
                <button type="submit">Submit</button>
            </fetcher.Form>
        </div>
    );
}

Expected Behavior

Page should stay at the same scroll position

Actual Behavior

Page is scrolled to the top

MattKintonCinch avatar May 09 '22 20:05 MattKintonCinch

Do you have the <ScrollRestoration/> component in your root.tsx?

kiliman avatar May 09 '22 20:05 kiliman

I do which is what's causing it, I'm just not sure that it's the right behaviour

ghost avatar May 09 '22 21:05 ghost

Hmm.. interesting. ScrollRestoration should only navigate to the top on route changes. I guess it sees a redirect as a route change despite it being the same route.

Since you're using fetcher.Form, is there a reason why you're redirecting? fetcher.Form doesn't do navigation, so it will just return the result and you can stay on the same page.

kiliman avatar May 09 '22 23:05 kiliman

This is for JS/non-JS support where I'm using the same action. In the non-JS version I want a redirect whereas in the JS version I want to stay on the same page, the logic is close the the Newsletter Sign Up example.

As far as I'm aware useFetcher will redirect if it recieves a redirect response but I don't think it should if you're on the same page. By the looks of it this is the funcionality of a normal Form submission see here.

I could write some custom logic to only return a redirect if I provide a certain field but that feels messy.

ghost avatar May 10 '22 09:05 ghost

I've added a PR which fixes the problem for me but I don't know if it's what the Remix team will want.

Also fixed the PR to use my actual personal account and not my work one :(

matt-kinton avatar May 11 '22 16:05 matt-kinton

@kiliman is correct in that a fetcher redirecting is a new location so it will cause scroll position to be reset. We recently added <Form preventScrollReset> in [email protected] but it looks like that doesn't make it through for <fetcher.Form> so we'll get that fixed.

Once we fix that, <fetcher.Form method="post" preventScrollReset={true}> should be what you need

brophdawg11 avatar Jan 23 '23 19:01 brophdawg11

This should be fixed in Remix 1.12.0 which should be deployed in the next hour or two

brophdawg11 avatar Jan 26 '23 18:01 brophdawg11

Released in 1.12.0

brophdawg11 avatar Jan 31 '23 15:01 brophdawg11