#refresh

1 messages · Page 1 of 1 (latest)

winged wyvern
#
"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
vague tuskBOT
#

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

winged wyvern
#

@vague tusk it still refreshes

vague tuskBOT
#

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.

For more information, you can refer to the MDN documentation on the History API (https://developer.mozilla.org/en-US/docs/Web/API/History_API).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: