-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat(remix-react): emulate put/patch/delete when JS is unavailable #4496
base: dev
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 18d6351 The changes in this PR will be included in the next version bump. This PR includes changesets to release 17 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
I titled this as a
|
72c840d
to
939dc6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love this, it makes other HTTP methods more reliable to use if you want to support a no-JS scenario
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!
(Although generally speaking, maybe we should start name-spacing remix special parameters like _remix_method
, _remix_data
..)
939dc6a
to
d37807f
Compare
d37807f
to
23d258a
Compare
Is it possible to make it work with |
23d258a
to
f1aea2e
Compare
@znycheporuk there are a couple big hurdles:
It may be possible to emulate it a different way, but that would require more plumbing and likely not be worth the trouble. One idea might be for remix to provide a function Button({ formmethod, name, value, ...props }) {
if (["put", "patch", "delete"].includes(formmethod)) {
name = "_method"
value = formmethod
}
return <button name={name} value={value} {...props} />
} A downside is that you couldn't use an explicit name+value in conjunction with such a I suspect it's probably not worth the trouble, and there may be a much simpler alternative if you want to associate a custom form method with a specific button: Use multiple forms :) ... for example, instead of this: <Form>
<input name="todoItem" defaultValue={myTodo} />
<button formmethod="put">Update</button>
<button formmethod="delete">Delete</button>
</Form> You could structure your elements like so: <>
<Form method="put">
<input name="todoItem" defaultValue={myTodo} />
<button>Update</button>
</Form>
<Form method="delete">
<button>Delete</button>
</Form>
</> Or if for some reason you really want the buttons in the same form (e.g. to facilitate styling), you can associate it with another form: <>
<Form method="put">
<input name="todoItem" defaultValue={myTodo} />
<button>Update</button>
<button form="delete-form">Delete</button>
</Form>
<Form method="delete" style={{ display: "none" }} id="delete-form"></Form>
</> If neither of those approaches work or your use case (e.g. you need all buttons to submit all the form data), then I'd suggest instead using buttons like |
c97f578
to
75f4cd5
Compare
References remix-run#4420 Ensure `<Form method=...>` behaves the same with and without JavaScript. Although native forms don't support PUT/PATCH/DELETE, we can emulate them by doing a POST and injecting a `_method` parameter into the action URL. The Remix server runtime then provides action handlers a `Request` with the overridden `method` so they are none the wiser. This provides a more reliable way to use these methods, which can be more ergonomic to write and handle than hidden inputs or buttons with values. Note: The emulation only works for action requests handled by Remix; if the form is submitted to another endpoint, it would need to handle the `_method` URL parameter accordingly.
75f4cd5
to
18d6351
Compare
As explained in #4420 (reply in thread), I don't think it's a good idea to make non-JS & JS work the same in this case
|
Happy to rebase/revisit this if we can get consensus from the Remix team... do we 1. want to move forward with emulation or 2. just want to deprecate those methods in v2 (or later?) I think there are good arguments to be made for and against either approach. My personal preference is emulation, but either option would be preferable to the inconsistent status quo. |
I think this should be considered in conjunction with remix-run/react-router#10324 (reply in thread). I think the crux of the question is "Should any version of One one hand, it would be nice if it could - and in this specific case we could do it with the approach here and it would "just work" with the users If we introduce But generally I think we should stay consistent. Either Definitely will need to get @mjackson and @ryanflorence to weigh in on a choice here. |
References #4420
Ensure
<Form method=...>
behaves the same with and without JavaScript. Although native forms don't support PUT/PATCH/DELETE, we can emulate them by doing a POST and injecting a_method
parameter into the action URL. The Remix server runtime then provides action handlers aRequest
with the overriddenmethod
so they are none the wiser.This provides a more reliable way to use these methods, which can be more ergonomic to write and handle than hidden inputs or buttons with values.
Note:
The emulation only works for action requests handled by Remix; if the form is submitted to another endpoint, it would need to handle the
_method
URL parameter accordingly.