Submit a form without overwriting existing parameters
This ExistingSearchParams component has been moved to Remix Utils
When you submit a GET form, the form data is serialized to a query string and appended to the URL, where the server will be able to read the data.
If there were any existing parameters in the URL, they will be overwritten. If you have a one form per page system, that makes sense because you'll want to make sure you're always using up-to-date values.
But if you have multiple forms on a page, you'll want to make sure that you're not overwriting the values of other forms.
You can solve this by looping through the existing parameters in the URL and print them out as hidden fields in the form. That way, when the form is submitted, the existing parameters will be preserved.
const [searchParams] = useSearchParams()const existingParams = Array.from(searchParams.entries())return ( <> {existingParams.map(([key, value]) => { return ( <input key={key} type="hidden" name={key} value={value} /> ) })} </>)
I've added this pattern to Remix Utils as a component called ExistingSearchParams
. It takes an optional exclude
prop.
Any parameters that should be excluded can be passed in as an array of strings.
- Most forms will want to exclude their own parameters so there's no duplication
- You can also use this to clear specific parameters, like resetting the page number when you submit a search form
import { ExistingSearchParams } from "remix-utils/existing-search-params"function SearchForm() { return ( <form method="GET"> <ExistingSearchParams exclude={["q", "page"]} /> <input type="text" name="q" /> <button type="submit">Search</button> </form> )}
Additional props can be passed to the hidden inputs by including them on the ExistingSearchParams component.
For example if you have a pre-existing form component and aren't able to add components inside of it, you can give that form an ID and attach the hidden inputs using the form
prop.
import { ExistingSearchParams } from "remix-utils/existing-search-params"import { SearchForm } from 'proprietary-search-form-library'function SearchPage() { return ( <SearchForm id="search-form" /> <ExistingSearchParams form="search-form" /> )}