Form Component #9856
Replies: 7 comments 17 replies
-
This seems very specific to REST api's and doesn't seem to be handling responses? https://github.com/react-hook-form/react-hook-form/pull/9735/files#diff-3141588a73e90d115af4c8ba465ba5a776a5d401d6d460a49d8f58b1193173d9R51-R92 And in general this seems to a specific handler implementation. Might it be an idea to split this stuff up? The handler is where the magic is. We, for example are using apolloClient and we wouldn't be able to use this in the current form. |
Beta Was this translation helpful? Give feedback.
-
We also created something similar for our usecase internally. And we found following additions very useful for our use case:
|
Beta Was this translation helpful? Give feedback.
-
I gave the new API a hypothetical go with a use case that I often deal with: The current form version would look like this: // outside the form, in a parent, mobx method maybe or similar code
const externalMethodThatDoesALotOfBusinessLogic = (validFormValues) => {
// I only need to submit some keys. For example, there was a confirmPassword maybe
// in there and the server is in JAVA, written by a different company, and it crashes if I
// don't send over the exact payload they need.
const {username, password, ...leaveTheRestAlone } = validFormValues
// call axiosInstance.post to a specific url, axios instances are preconfigured with a baseURL, some headers etc
// full url might be someotherdomain.com/api/create. Logged out errors are handled inside the form, and inlcudes
// an auth token or some additional headers not present in the form
try {
const response = mySpecificBackendInstance.post("/create", {username, password})
if ( isOKBySomeBusinessLogic(response) ) {
myRouterSolution.push("/some-path")
} else {
myFormRef.current.setFieldErrors(someWayOfMappingResponseDataToFieldErrors(response))
}
} catch (err) {
logSentryError(err)
}
}
// in the form
const { handleSubmit } = useForm();
return <form onSubmit={handleSubmit(props.externalMethodThatDoesALotOfBusinessLogic)} /> A rewrite with the new Form component would probably look like: // outside the form, in a parent, mobx method maybe or similar code
// I'm handling success and maybe non server errors here?
const handleSuccess = (responseSuccess) => {
// call axiosInstance.post to a specific url, axios instances are preconfigured with a baseURL, some headers etc
// full url might be someotherdomain.com/api/create. Logged out errors are handled inside the form, and inlcudes
// an auth token or some additional headers not present in the form
try {
if ( isOKBySomeBusinessLogic(response) ) {
myRouterSolution.push("/some-path")
} else {
myFormRef.current.setFieldErrors(someWayOfMappingResponseDataToFieldErrors(response))
}
} catch (err) {
logSentryError(err)
}
}
const handleError = (response) => {
myFormRef.current.showFormError("Maybe a generic message about something wrong on the server")
logSentryError(err)
}
<Form
// my form now only works with one endpoint, I need to add another prop for this to work
// with a different endpoint. It also know knows about the server. Previously, it did not.
// how do I strip some fields out of the payload?
action="//someotherdomain.com/api/create"
method="post" // default to "post"
// I have not split my top down readable code that handles submissions, loading, error and success
// into a ping pong between the handler code, the error code and the RHF internal code
onError={props.handleSubmissionError}
// I actually kinda like onSuccess to be honest, not sure why, but having the router
// redirect be passed like seems right.
onSuccess={props.handleSuccess}
// I'm not sure where my isOKBySomeBusinessLogic method would be called,
// or how I would decide if a 200 STATUS code response with some key in the JSON response is actually
// an edge case. if I can't do this, it means again I need to know more than I did before in order to achieve
// the same result.
> For me, since most of the forms that I work on have either one or more of this additional concerns, this new API is not very helpful, but not harmful at all. However, for less experience developers, especially juniors / mids working in outsourcing companies (where I happen to teach this wonderful form library that I really love and I hope this feedback is not taken negatively :D ) this will be a gateway of writing code in a different way than other components that deal with API calls in their application, and a way of mixing error logging, headers and urls with a component that up until now worked perfectly in isolation. |
Beta Was this translation helpful? Give feedback.
-
Writing another coment with a different concern, regarding the Right now, a form that uses |
Beta Was this translation helpful? Give feedback.
-
Canary version: #9896 |
Beta Was this translation helpful? Give feedback.
-
Hey @bluebill1049 so as i understand this syntax for declaring default values type and output values type isnt supported via useForm hook as you suggested ? We have to use Form Component in order to achieve this? |
Beta Was this translation helpful? Give feedback.
-
Hello, looks like I didn't get if this Form component is supported in NextJS. |
Beta Was this translation helpful? Give feedback.
-
💁♂️ Summary
This proposal is made so we can discuss and find a proper and better developer experience to handle the form submission. Improve progress enhancement for existing form applications that are server-rendered eg NextJs.
👋🏻 Motivation
I am building a form builder application BEEKAI, during the development progress I found myself repeating the same code block for writing form submissions in multiple instances, including error handling and success handler. Over time, it creates inconsistency in the codebase, so I decided to build a
Form
component within the app to improve the following📖 Design/Proposal
Introduce the new
Form
component, and here are some of the features I would like to cover:action
,method
PR: #9735 (WIP)
The following is the full API design:
Default: Use case 1 (Post submission with FormData):
The following code will be executed internally:
Use case 2 (Post submission with JSON):
The following code will be executed internally:
Use case 3 (Manual submission):
Use case 4 (React Native headless):
Use case 5 (Remix, SWR, Tan Query):
😢 Drawbacks
⛔️ Limitation
🙋♂️ Unresolved questions
Do we have any better approach or suggestions?
Beta Was this translation helpful? Give feedback.
All reactions