Add submitOptions
argument for useSubmit
and useFetcher
#9737
Replies: 5 comments 14 replies
-
As a note, this closes remix-run/remix#4872 in Remix |
Beta Was this translation helpful? Give feedback.
-
This was actually my first design for Init vs. call site conflicts?What are the semantics when the init and the call site are different? function Thing() {
let fetcher = useFetcher({
method: 'post',
action: '/some-path',
})
return (
<fetcher.Form method="get" action="/other-path">
<button name="hi" value="bob" />
</fetcher.Form>
)
} Future APII've also been planning to use the init for "events" but haven't had a chance to write out the proposal yet. useFetcher({
onStart() {},
onError() {},
onSuccess() {},
onComplete() {},
}); But those might be better configured at the call site too: Please don't turn this thread into a comment about these events, just want to point out that there might be something else we want to use the fetcher init for. Fetcher Render Stability?I'm unclear on this part. https://stackblitz.com/edit/node-zryjnr?file=app/routes/index.tsx import { useFetcher } from '@remix-run/react';
import { useEffect, useState } from 'react';
export default function Index() {
let fetcher = useFetcher();
let [effectCalls, setEffectCalls] = useState(0);
let [updates, setUpdates] = useState(0);
useEffect(() => {
setEffectCalls(effectCalls + 1);
}, [fetcher]);
return (
<div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>
<h1>Effect Calls: {effectCalls}</h1>
<button onClick={() => setUpdates(updates + 1)}>
Internal Updates: {updates}
</button>
</div>
);
} Clicking the button does not cause the effect to run. |
Beta Was this translation helpful? Give feedback.
-
Alright, I've thought about this for a bit and I'm not super interested in it. Since we've established that stable "submit" across location changes is not related to the signature change, I'm not sure what the value prop is here other than a bit of API preference. Technically you need call site options, but you don't need init options. So a signature change is a "Convenience API", which we tend to shy away from. We've also talked about passing an app supplied In other words, is a convenience API worth preventing (or complicating) future use cases? I'd say no. I'm pretty sure all you need is this if you want it: function useFetcherWithDefaults(defaults) {
let fetcher = useFetcher();
return useMemo(() => {
return {
...fetcher,
submit: (formData, options) => {
return fetcher.submit(formData, { ...defaults, ...options });
},
}
}, [fetcher]);
} |
Beta Was this translation helpful? Give feedback.
-
This could be solved easily if the ID was a param in the options object, a la |
Beta Was this translation helpful? Give feedback.
-
This should now be fixed by #10336 |
Beta Was this translation helpful? Give feedback.
-
This would allow folks to change their code from something like this:
To this:
(While still supporting the old API as well).
I've seen some folks suggest they would actually prefer this API and I think I agree with them. Also, it would side-step the problem of fetcher being referentially stable (#9739).
I've already implemented this in
@remix-run/react
here: remix-run/remix#4882Until this is implemented, the only way to reliably use a
fetcher.submit
in a dep array is to do something like this:The drawback here is that if we actually do depend on the
defaultAction
then it's possible we'll get the wrong one when submit is called.This PR fixes that by allowing users to specify an
action
(among other submit options):As instructed, I've opened this discussion here because this is where the final implementation of fetcher code will live going forward.
Let me know how I can help. Hopefully it's easy to implement, document, and test because I've already got that PR as a reference.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions