React form not submitting when using button nested inside Link tag

Viewed 140

In my app I have an order form with a button to "complete order" at the bottom. What I want the button to do is submit the form and push the user to the confirmation page where their order will be displayed. Right now I can do one or the other, but can't figure out how to to both.

My form component:

<form onSubmit={onSubmit}>
    <label>Name:
        <input 
            type="text"
            name="name"
            placeholder="Name"
            value={values.name}
            onChange={onChange}
        />
    </label>
    <Link to="/confirmation" >
        <button>Complete Order</button>
    </Link>
</form>

My onSubmit function:

const formSubmit = () => {
  const newOrder = {
    name: formValues.name.trim(),
  }

  setOrder(order.concat(newOrder));
  setFormValues(initialFormValues);
}

I can tell my formSubmit function submit isn't working because my formValues don't reset after form submission. If I remove the Link tag and just have the button, they do, but then I don't get the redirect to the confirmation page. Any suggestions on what I can do?

1 Answers

If you want to update/reset the form state then navigate to the "/confirmation" path, you can't use a Link and a button/submit the form at the same time.

Remove the Link component and issue an imperative navigation after enqueueing the state updates. Don't forget to prevent the default form action from occurring so the app isn't reloaded.

import { useNavigate } from 'react-router-dom';

...

const navigate = useNavigate();

...

const onSubmit = (e) => {
  e.preventDefault();

  const newOrder = {
    name: formValues.name.trim(),
  };

  setOrder(order.concat(newOrder));
  setFormValues(initialFormValues);
  navigate("/confirmation");
}

...

<form onSubmit={onSubmit}>
  <label>Name:
    <input 
      type="text"
      name="name"
      placeholder="Name"
      value={values.name}
      onChange={onChange}
    />
  </label>
  <button type="submit">Complete Order</button>
</form>
Related