"use client"
import { useRouter, useSearchParams, usePathname } from "next/navigation";
export default function SortAndFilter({ itemsLength }: { itemsLength: number }) {
const searchParams = useSearchParams();
let min: undefined | null | string = searchParams.get('min')
let max: undefined | null | string = searchParams.get('max')
let sortType: undefined | null | string = searchParams.get('sortType')
let name: undefined | null | string = searchParams.get('name')
min = min === null ? undefined : min
max = max === null ? undefined : max
sortType = sortType === null ? undefined : sortType
name = name === null ? undefined : name
const router = useRouter();
const currPathName = usePathname()
const newSearchParams = new URLSearchParams(searchParams.toString());
function addParam(key: string, value: string) {
newSearchParams.set(key, value)
router.push(${currPathName}?${newSearchParams.toString()})
}
function removeParam(key: string) {
newSearchParams.delete(key)
router.push(${currPathName}?${newSearchParams.toString()})
}
return <div>
<h3>{itemsLength} items</h3>
<div>
<div>
<label>Price </label>
<select onChange={e => addParam("sortType", e.target.value)}
value={sortType || PRICE_SORT.LOW_TO_HIGH.toString()}>
<option value={PRICE_SORT.LOW_TO_HIGH.toString()}>Low to high</option>
<option value={PRICE_SORT.HIGH_TO_LOW.toString()}>High to low</option>
</select>
</div>
<div>
<label >Price range </label>
<div>
<label>Min: </label>
<input
value={min undefined}
min={0}
onChange={e => {
if (e.target.value.toString() === "") {
removeParam('min')
}else if (e.target.valueAsNumber >= 0) { addParam("min", e.target.value) }}
}
type="number" />
</div>
}```
It refreshes every time i type something into input, i dont want refr
#refresh
1 messages · Page 1 of 1 (latest)
Hi @winged wyvern. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
The behavior you're experiencing is due to the fact that every time you call router.push, it triggers a navigation event and re-renders the component. This is the expected behavior in Next.js.
However, if you want to avoid a full page refresh when updating the URL, you can use the router.replace method instead of router.push. The router.replace method updates the URL without adding a new entry to the history stack, thus it doesn't cause a full page refresh.
Here's how you can modify your addParam and removeParam functions:
function addParam(key: string, value: string) {
newSearchParams.set(key, value)
router.replace(`${currPathName}?${newSearchParams.toString()}`)
}
function removeParam(key: string) {
newSearchParams.delete(key)
router.replace(`${currPathName}?${newSearchParams.toString()}`)
}
Please note that this will only prevent a full page refresh. The component itself will still re-render because its state (in this case, the URL) is changing. If you want to prevent unnecessary re-renders, you might need to optimize your component using techniques like memoization.
For more information, you can refer to the Next.js documentation on the useRouter (https://nextjs.org/docs/app/api-reference/functions/use-router) hook.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@winged wyvern kapa.ai is still learning and improving, please let us know how it did by reacting below
@vague tusk it still refreshes
Let me check the knowledge base for you. One moment! :books:
I see, it seems like you're experiencing an issue where the component re-renders every time the URL's query parameters change. This is a known issue in Next.js and there's an open discussion about it on GitHub (source (https://github.com/vercel/next.js/issues/43691)).
One workaround suggested in the discussion is to use the window.history.replaceState method instead of Next.js's router methods. Here's how you can modify your addParam and removeParam functions:
function addParam(key: string, value: string) {
newSearchParams.set(key, value);
const newUrl = `${currPathName}?${newSearchParams.toString()}`;
window.history.replaceState({ ...window.history.state, as: newUrl, url: newUrl }, '', newUrl);
}
function removeParam(key: string) {
newSearchParams.delete(key);
const newUrl = `${currPathName}?${newSearchParams.toString()}`;
window.history.replaceState({ ...window.history.state, as: newUrl, url: newUrl }, '', newUrl);
}
Please note that this is a workaround and might not work in all cases. The Next.js team is aware of this issue and a solution is on the roadmap (source (https://github.com/vercel/next.js/issues/49668)).
Also, keep in mind that using window.history.replaceState will not trigger Next.js's router events. If you have any logic that depends on these events, you might need to handle it differently.