Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revalidation triggers fetcher.submit to change #4872

Closed
kentcdodds opened this issue Dec 15, 2022 · 3 comments
Closed

Revalidation triggers fetcher.submit to change #4872

kentcdodds opened this issue Dec 15, 2022 · 3 comments
Labels
bug Something isn't working

Comments

@kentcdodds
Copy link
Member

What version of Remix are you using?

1.8.2

Steps to Reproduce

Open this: https://stackblitz.com/edit/node-ikzu57?file=app%2Froutes%2Findex.tsx

Open the browser console

Click "Set searchParams"

Observe the console shows that fetcher.submit has changed.

Expected Behavior

I expect fetcher.submit to be stable so I can safely use it in dependency arrays.

Actual Behavior

I cannot use fetcher.submit in a dependency array because any time there's a revalidation on the page, all fetcher.submits are new instances of the submit function.

@kentcdodds
Copy link
Member Author

After further investigation, what's trigger fetcher.submit to change is the defaultAction dependency:

let defaultAction = useFormAction();

So, what's happening, is I make a change to the URLSearchParams, that triggers the defaultAction to change which invalidates the submit on the fetcher which triggers my useEffect again.

In my case, I don't care about the defaultAction because I specify one when I call submit.

So, in order to ensure referential stability, we need to either:

  1. allow the user to configure the action when calling useFetcher so we can ignore the defaultAction in that case (so it won't appear in the dependency array and therefore cannot change)
  2. Or we need to use a "latest ref" pattern so we don't have to list the defaultAction in the dependency array.

I much prefer option 1 because it would actually be a really nice feature to have anyway. It would allow folks to change their code from something like this:

const fetcher = useFetcher()

// ...
<button onClick={() => fetcher.submit({hi: 'bob'}, {method: 'post', action: '/some-path'})}>Submit bob</button>

To this:

const fetcher = useFetcher({
  method: 'post',
  action: '/some-path',
})

// ...
<button onClick={() => fetcher.submit({hi: 'bob'})}>Submit bob</button>

I've seen some folks suggest they would actually prefer this API and I think I agree with them. Also, it would solve the problem of fetcher being referentially stable.

@brophdawg11
Copy link
Contributor

This should be resolved by remix-run/react-router#10336 which makes fetcher.submit stable across location changes

@brophdawg11 brophdawg11 self-assigned this Apr 14, 2023
@brophdawg11 brophdawg11 added bug Something isn't working awaiting release This issue has been fixed and will be released soon and removed bug:unverified labels Apr 14, 2023
@brophdawg11
Copy link
Contributor

brophdawg11 commented Apr 21, 2023

Should be available in Remix 1.16 once released

@brophdawg11 brophdawg11 removed their assignment Apr 21, 2023
@brophdawg11 brophdawg11 removed the awaiting release This issue has been fixed and will be released soon label Dec 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants