(Next.js) I have a GET form on one page. I want to submit it to another page. I know I can set the action
property to the other page. That works. However, it does a page reload instead of just rendering the new page; the same as would happen if you had a link on the page without wrapping it in a Link
component.
I could catch the submit event, build a query, and push it onto the router. But that seems like a lot of extra work for something I assume has already been figured out.
Any ideas how to do this without reinventing the wheel?
<form method='get' action='/search'>
<input name='q' placeholder='Search' arial-label='Search' />
</form>
(Next.js) I have a GET form on one page. I want to submit it to another page. I know I can set the action
property to the other page. That works. However, it does a page reload instead of just rendering the new page; the same as would happen if you had a link on the page without wrapping it in a Link
component.
I could catch the submit event, build a query, and push it onto the router. But that seems like a lot of extra work for something I assume has already been figured out.
Any ideas how to do this without reinventing the wheel?
<form method='get' action='/search'>
<input name='q' placeholder='Search' arial-label='Search' />
</form>
Share
Improve this question
asked Jan 23, 2020 at 23:32
CullyCully
6,9556 gold badges42 silver badges63 bronze badges
2
|
2 Answers
Reset to default 24I ended up catching the submit event and pushing a URL onto the router.
import {useState} from 'react'
import {useRouter} from 'next/router'
const preventDefault = f => e => {
e.preventDefault()
f(e)
}
export default ({action = '/search'}) => {
const router = useRouter()
const [query, setQuery] = useState('')
const handleParam = setValue => e => setValue(e.target.value)
const handleSubmit = preventDefault(() => {
router.push({
pathname: action,
query: {q: query},
})
})
return (
<form onSubmit={handleSubmit}>
<input
type='text'
name='q'
value={query}
onChange={handleParam(setQuery)}
placeholder='Search'
aria-label='Search'
/>
</form>
)
}
Based on the Next.js' routing system and Router API:
The Next.js router allows you to do client-side route transitions between pages, similarly to a single-page application. A special React component called Link is provided to do this client-side route transition.
Router.push also handles client-side transitions, and this method is useful for cases where next/link is not enough.
So it seems that you can only perform client-side transitions by using any of those two ways.
Using the form above will trigger a behavior as described by MDN docs for a form submission, as none of the above rules applies:
...The server then responds, generally handling the data and loading the URL defined by the action attribute, causing a new page load (or a refresh of the existing page, if the action points to the same page).
I also found another reference close to your question in Next.js' issues board, where the preferred method to follow, was the one you've also described as a solution.
Link
. – Cully Commented Jan 24, 2020 at 20:12