Formik: Use `action` attribute on `form` element.

Created on 5 Apr 2018  路  18Comments  路  Source: formium/formik

Bug, Feature, or Question?

Question

Stupid question but is it possible to use action='/api' method='POST' instead of ajax? I am trying to use it but its not working for me. Is there a prop I have to supply?

  • Formik Version: 0.11.11
  • React Version: 16.2.0
  • TypeScript Version: N/A
  • CodeSandbox Link: N/A
  • OS: Mac OS X 10.13.3
  • Node Version: 8.0.0
  • Package Manager and Version: NPM, 5.8.0

Most helpful comment

I feel sorry for anyone who stumbles across this thread because they are in for a world of confusion.

The answer to the original questions is yes you can use action='/api' method='POST' instead of ajax and the working demo is here: https://codesandbox.io/s/826qv6lv7l 鉁岋笍

All 18 comments

@ankurkaushal360 did you solve this? I'd love to know how!

What鈥檚 the point in using Formik if you don鈥檛 want to submit your form data with JavaScript?

Our team is working on some OAuth flows within a next.js app. An XHR POST that responds with a redirect code (e.g. 302) will cause the browser to initiate another XHR request but _will not_ cause the browser to redirect the user to a new location. On the other hand, a standard HTML form POST that responds with a redirect code _will_ cause the browser to redirect the user, so that's where we've landed. Now our formik logic isn't working. We may have to achieve this with another approach if it's not really doable via formik.

I still don't really understand what you are looking for. Formik puts your from values in memory so you can use them easily with JS/React. If you want to do a regular form POST action it will use the values that are in the DOM. These are two completely different things and you can't mix them together.

Why don't you use redirect manually in your XHR handler after you get a response from the server?

I just spent the last few days building out this form only to realize the form won't submit with action. Like @rovansteen said, it seems like they are 2 completely different things but oddly enough you can't do a normal action post. Creating a regular form without Formik and submitting will reload the page as expected:

import React from 'react';

const Form = () => {
  return (
    <form>
        <input id="example" type="text" name="text" />
        <input type="submit" value="Send" />
    </form>
  )
}

export default

but with Formik, no reload happens. If you inspect the state you'll still see the submit count go up but the submission actually never happens.

const MyForm = props => {
  const { values, handleChange, handleBlur, handleSubmit } = props;

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        onChange={handleChange}
        onBlur={handleBlur}
        value={values.name}
        name="name"
      />
      <button type="submit">Submit</button>
    </form>
  );
};

const MyEnhancedForm = withFormik({
  mapPropsToValues: () => ({ name: '' }),
  handleSubmit: (values, { setSubmitting }) => {
    setSubmitting(false);
  }
})(MyForm);

This is either a bug or needs to be stated in the docs or README cause I just spent a ton of time building a large form only to find out now it won't work. Also hate to @ you directly, but @jaredpalmer you think you can shed some light on this? Just lost a few days worth of work because of this and would ideally like to keep using Formik!

That鈥檚 because the Formik鈥檚 handleSubmit prevents the submit event鈥檚 default behavior. You could pass your own handler to the form element but then you lose out on a lot of the benefits of Formik. I really don鈥檛 understand why you want to combine vanilla HTML forms with Formik.

@rovansteen not every thing has to be a single page app and there are plenty of reasons to use a regular forms with the action attribute. @lisamartin00 had a good one. In my case, I am using rails and can redirect with instance variables for the view I redirect to. Now I have to make multiple ajax calls to fetch data I could easily just get through a normal form post and redirect.

I totally get why you would want a normal form. But I don鈥檛 get why you want to use Formik then? If vanilla HTML forms does the job for your use case why are you complicating things by adding Formik to the mix?

What鈥檚 the point in using Formik if you don鈥檛 want to submit your form data with JavaScript?

Glad you asked! Straight from Formik's README:

Formik is a small library that helps you with the 3 most annoying parts:
1. Getting values in and out of form state
2. Validation and error messages
3. Handling form submission

Even when using HTML forms, one can still draw value from Formik for 1 and 2.

Formik puts your from values in memory so you can use them easily with JS/React. If you want to do a regular form POST action it will use the values that are in the DOM. These are two completely different things and you can't mix them together.

I disagree with your premise here. Formik is an extension of React and React is designed to control the DOM. Even the React Forms docs show that React itself doesn't get in the way of initiating the default form submission event. Quite the opposite in fact, because you the developer need to explicitly call e.preventDefault() if you want to handle the form submission via xhr.

One reason why Formik prevents the default form submission is because Formik supports asynchronous validation via the validate function. If the form's onSubmit returns, then the default submission would occur before the async validation has a chance to run. Given that, the only way that I can see to use Formik with HTML form posts is to submit the form via javascript yourself:

const formEl = useRef(null);

...

 const handleSubmit = values => {
  formEl.current.submit();
};

...

<form action="/path" ref={formEl}> ...

Full demo here: https://codesandbox.io/s/826qv6lv7l

@rovansteen because the form im building is long and somewhat complex. Regardless of complexity and length, vanilla html forms in react are messy, especially when you add validation and have to deal with the submission part. Formik even says states the 3 reasons I am using it in the README. Nothing in it states that you can't use a action attribute post.

I'm not sure why you think a form using the action attribute should just use vanilla html. Say I have a long complex tax form to create that uses an action post, and simple email and password form that uses an ajax post, then I would want to use something like formik to manage state/validations. How it is submitted should not matter since this is just a form builder. Hope that clears it up!

@goldenshun

I disagree with your premise here. Formik is an extension of React and React is designed to control the DOM. Even the React Forms docs show that React itself doesn't get in the way of initiating the default form submission event. Quite the opposite in fact, because you the developer need to explicitly call e.preventDefault() if you want to handle the form submission via xhr.

I'm not stating that React doesn't work well with vanilla HTML forms, I'm talking about Formik. They are fundamentally different as the values from Formik are in memory but the values from a HTML form are in the DOM.

<Formik initialValues={{ first_name: 'John', last_name: 'Doe' }}>
  <form>
    <input name="first_name" />
  </form>
</Formik>

If you would submit this form without Formik it would only contain a first_name, but if you submit it with Formik it has both first_name and last_name.

@goldenshun

I'm not sure why you think a form using the action attribute should just use vanilla html.

I'm not saying that. React !== Formik.

How it is submitted should not matter since this is just a form builder.

This is not true, Formik isn't just a form builder it's more a form manager; it holds the values, it validates them etc.

Formik is a great library but it's opinionated in the fact that it expects you to use JavaScript to manage it completely. I'm sure there are other form libraries in React out there that do work well together with the HTML <form> element.

@rovansteen

the values from Formik are in memory

Except in the withFormik example, Formik is managing the DOM too: https://jaredpalmer.com/formik/docs/api/withformik

I also provided a full working demo that shows how you can use Formik with HTML forms. Is there a problem with that demo? It allows you to use Formik _and_ support an HTML form post. What am I missing?

@goldenshun no Formik doesn't manage the DOM, React does because you tell it to do so in your component. There's nothing wrong with your example, it's just a workaround. Personally I would use another form library that works better together with HTML forms.

@goldenshun look at this forked example, Formik has the firstName in it's values, even tho there is no actual input with that name. https://codesandbox.io/s/pkjp0rwmx0

I feel sorry for anyone who stumbles across this thread because they are in for a world of confusion.

The answer to the original questions is yes you can use action='/api' method='POST' instead of ajax and the working demo is here: https://codesandbox.io/s/826qv6lv7l 鉁岋笍

@goldenshun thanks for the workaround example! I still think this should be in the docs but hopefully someone can find this thread if they need to use the action attribute

@goldenshun thank you! Very helpful.

@goldenshun thanks for the example, super helpful! Not sure if you meant this, but your example code doesn't include method='POST' as your comment implies.

The answer to the original questions is yes you can use action='/api' method='POST' instead of ajax and the working demo is here: https://codesandbox.io/s/826qv6lv7l 鉁岋笍

Was this page helpful?
0 / 5 - 0 ratings

Related issues

giulioambrogi picture giulioambrogi  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

dfee picture dfee  路  3Comments

pmonty picture pmonty  路  3Comments