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

Explain how to handle submission of field values #22

Closed
a-type opened this issue Jan 17, 2020 · 2 comments · Fixed by #25
Closed

Explain how to handle submission of field values #22

a-type opened this issue Jan 17, 2020 · 2 comments · Fixed by #25
Labels
Documentation Improvements or additions to documentation

Comments

@a-type
Copy link

a-type commented Jan 17, 2020

Maybe I missed it, but I'm not seeing any guidance in the docs on how to actually respond to form submission, gather field values and send them to an API or otherwise utilize them.

It seems like the user is expected to attach a submit handler to the <form> or <button type="submit"> elements, and then read the form state from const formState = useForm(), i.e. formState.fields.foo.value, etc. Is that right?

While it makes sense from a "thinking with hooks" perspective, this is a significant departure from what users are used to with incumbent solutions like Formik, which all revolve around providing an explicit onSubmit handler which receives the gathered values directly.

The Getting Started docs probably need a full explanation of how to actually handle form submission and extract values.

If there's no more convenient way to pull the entire set of field values than referencing formState.fields.foo.value on every one of them, I'd also suggest we figure out something more convenient. Ideally I'd want a plain structured object of field values.

Perhaps an onSubmit handler function could also be passed to useForm() for the sake of being a bit more intuitive for newcomers (there's danger in opening multiple pathways to functionality, of course)?

const handleSubmit = useCallback(values => {
  sendToApi(values);
}, [sendToApi]);

const formState = useForm({ handleSubmit });

// etc

Finally, because this is a field-centric library, for TypeScript users the documentation should probably indicate clearly that you must pass a field schema type to useForm<FieldSchema>() for field values to be typed and accessible in the form state. While that's intuitive, I've seen this problem trip up other new TypeScript users who aren't used to conventions yet.

Let me know how I can assist on any of these! I'm happy to contribute.

@andyrichardson
Copy link
Owner

andyrichardson commented Jan 20, 2020

Hey @a-type thanks for creating this issue! Full breakdown below.

Why there's no 'handleSubmit'

this is a significant departure from what users are used to with incumbent solutions like Formik, which all revolve around providing an explicit onSubmit handler which receives the gathered values directly.

Fielder is a huge departure from the approach of libraries such as Formik, and this is intentional.

Because of how the field-level implementation works, we don't make any assumption about a "final desired state" - hence why validation isn't declared upfront and neither is the submit handler.

This means working with more dynamic forms where branching is involved is much easer.

Untitled Diagram (7)

This could be improved

That being said, I can completely see where the confusion is coming from and this is definitely something that I'm going to have to add to the docs!

For the time being, you'll want to declare your submit/progression handler in the component where the progressive action (i.e. submit button click) is declared.

Here's an example

const EmployerSubmissionStep = () => {
  const { fields, isValid } = useFormContext();
  const [employerFieldProps] = useField('employer');

  const handleSubmit = useCallback(() => {
    const submissionValues = Object.entries(fields).reduce(
      (v, [key, field]) => ({ ...v, [key]: field.value }), {}
    );

    fetch('/employee', {
      method: 'POST',
      json: JSON.stringify(submissionValues)
    })
  }, [fields]);
 
  return (
    <div>
      <input type="text" {...employerFieldProps} />
      <button onClick={handleSubmit} disabled={!isValid}>Submit</button>
    </div>
  )
}

I appreciate that many people don't like using reduce so I may create a utility function to do this behind the scenes.

@andyrichardson andyrichardson added the Documentation Improvements or additions to documentation label Jan 20, 2020
@andyrichardson
Copy link
Owner

@a-type the docs for submission are now live

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants