jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.87k stars 2.78k forks source link

When submitting form fails, select dropdown does not maintain proper value #1452

Open ekingan opened 5 years ago

ekingan commented 5 years ago

When submitting form fails, select dropdown does not maintain the proper value

I am using React, Formik, and react-select. I am having trouble with a dropdown select field for country.

Before I submit the form, I can see that the form has both a value and a label:

console.log(this.props.values.billing_information_attributes.address_attributes.country )

returns this {value: "United States", label: "United States"}

After I submit the form and the post request responds with a failure (this is a desired failure for test purposes), all other forms retain their values with the exception of this dropdown. Now the same console.log returns only "United States"

For the dropdown to work, it needs to be provided an object in the format mentioned before {value: "United States", label: "United States"} or the dropdown appears blank. Obviously, I could instrument a work around and set the field value again using setFieldValue, but I feel I am missing something in regards to the Formik lifecycle. One other important thing to mention is that before I send the post request I am modifying the data I send to the server and only sending the value of the country, not the entire value and label object, like this:

newParams["billing_information_attributes"]["address_attributes"]["country"] =
params["billing_information_attributes"]["address_attributes"]["country"].value

Here is my post request:

handleSubmit = (params, actions) => {
    Stripe.card.createToken(
      {
        number: params.card_number,
        cvc: params.security_id,
        exp_month: params.exp_month,
        exp_year: params.exp_year,
        address_zip: params.billing_information_attributes.address_attributes.postal_code
      },
      (status, response) => {
        params.stripe_card_token = response.id
        axios
          .request("/order/complete", {
            method: "patch",
            data: {
              order: modifiedParams(params, "checkoutForm"),
              authenticity_token: this.props.authenticity_token,
              agree_to_terms: params.agree_to_terms,
              save_new_card: params.save_new_card,
              saved_cards: params.saved_cards.value
            }
          })
          .then(({ data }) => {
            if (data.success) {
              actions.resetForm()
              actions.setStatus({ message: data.message })
              window.location.replace("/order/" + data.order_id)
            } else {
              actions.setErrors({ server: data.errors })
              actions.setStatus({ message: data.message})
              console.log(data)
            }
            actions.setSubmitting(false)
            document.querySelector(".flashMsg").scrollIntoView({ behavior: "smooth" })
          })
          .catch(error => {
            console.log(error)
            actions.setSubmitting(false)
            actions.setErrors({ server: ["Cannot submit form at the moment. Please try again."] })
            document.querySelector("body").scrollIntoView({ behavior: "smooth" })
          })
      }
    )
  }

Can anyone help figure out why the values of this field change after submit? Thanks!

jarleriksen commented 5 years ago

I have noticed the same in my forms using react-select.

This also only occurs when I transform the data after submitting and the backend returns an error. It doesn't matter if I transform the data in my onSubmit function or in a redux action. I still experience the same issue. If no transformation of data happens, there are no issues.

A console.log while submitting shows that my transformed values from my onSubmit gets passed down to the form again, and Formik sets those as the values instead of the original form values.

I feel like I am missing something since that happens.

Would also love to get some help on this. Been experiencing it for a while. Thanks!

ekingan commented 5 years ago

@jarleriksen How did you resolve the issue? Did you convert the data on the server side or on the client side when the data gets returned to the form after submit?

jarleriksen commented 5 years ago

@ekingan I haven't solved it yet. I've just been lucky that the request has never failed so far. But I would really like to solve it.

IsaacTrevino commented 4 years ago

I just submitted an issue with Stripe here for it might be related. stripe/stripe-react-js#109

I believe when you press the submit button the form is re-rendered by some state variable within formik. Thus wiping your stored data.

Any help would be appreciated.