'Link tag not triggering onSubmit when clicking on the form's submit button
For some reason when I wrap my Link tag around my form's submit button it doesn't trigger the onSubmit() function. What am I doing wrong?
import { Link } from "react-router-dom";
<form className="gift-search" onSubmit={onSubmit}>
<div>
<input
type="text"
name="giftSearch"
placeholder="Search for any gifts"
onChange={onChange}
/>
</div>
<Link to={{ pathname: `/category/${giftSearchState}` }}>
<button type="submit" className="search-btn">
Search
</button>
</Link>
</form>
Solution 1:[1]
I would navigate programmatically using useNavigate()
:
const navigate = useNavigate();
const onSubmit = (e) => {
e.preventDefault();
navigate(`/category/${giftSearchState}`);
}
...
<form className="gift-search" onSubmit={onSubmit}>
<div>
<input
type="text"
name="giftSearch"
placeholder="Search for any gifts"
onChange={onChange}
/>
</div>
<button type="submit" className="search-btn">
Search
</button>
</form>
Solution 2:[2]
There is nothing wrong with your code.
Internally, the react-router-dom Link
component will render an html link <a>
with the children (in this case your button).
You can see the Link
source code here.
But the problem is not that, I created a sandbox example using the button inside a <a>
and inside a <Link>
, and you can check for yourself that when you have a button inside a <a/>
, if the button has the type=submit, then the form onSubmit will be called.
The problem is following:
The Link
component has its own onClick function internally and it calls the preventDefault
to allow only the back button click, you can see at this line
So, what is happening is:
Your button is clicked, and the event is captured and not prevented, then the Link captures the event and call the preventDefault so it will never reach your onSubmit
form function.
In the codesand, I let a console.log in the button onClick so you can see that the event.button
is equal to 0
The react-router-dom source code is really interesting, I recommend you to take a look :)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Monstar |
Solution 2 | Thomaz Capra |