From bbdcd358dfad35825c70a2160e1c0e710f8b5509 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Sat, 13 Aug 2022 14:36:34 -0700 Subject: [PATCH] Make useQueryAndSortParams machinery fast --- web/hooks/use-sort-and-query-params.tsx | 55 ++++++++++++++----------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/web/hooks/use-sort-and-query-params.tsx b/web/hooks/use-sort-and-query-params.tsx index e917e4af..75ba06fc 100644 --- a/web/hooks/use-sort-and-query-params.tsx +++ b/web/hooks/use-sort-and-query-params.tsx @@ -1,6 +1,5 @@ -import { debounce } from 'lodash' import { useRouter } from 'next/router' -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useState } from 'react' import { DEFAULT_SORT } from 'web/components/contract-search' const MARKETS_SORT = 'markets_sort' @@ -32,22 +31,38 @@ export interface QuerySortOptions { disableQueryString?: boolean } +function withQueryParams( + location: Location, + params: { [k: string]: string | null | undefined } +) { + const newParams = new URLSearchParams(location.search) + for (const [k, v] of Object.entries(params)) { + if (!v) { + newParams.delete(k) + } else { + newParams.set(k, v) + } + } + const newUrl = new URL(location.href) + newUrl.search = newParams.toString() + return newUrl +} + export function useQueryAndSortParams({ defaultSort = DEFAULT_SORT, shouldLoadFromStorage = true, disableQueryString, }: QuerySortOptions = {}) { const router = useRouter() - const { s: sort, q: query } = router.query as { q?: string s?: Sort } const setSort = (sort: Sort | undefined) => { - router.replace({ query: { ...router.query, s: sort } }, undefined, { - shallow: true, - }) + const history = window.history + const url = withQueryParams(window.location, { s: sort }).toString() + history.replaceState({ ...history.state, as: url, url }, '', url) if (shouldLoadFromStorage) { localStorage.setItem(MARKETS_SORT, sort || '') } @@ -60,17 +75,11 @@ export function useQueryAndSortParams({ }, [query]) // Debounce router query update. - const pushQuery = useMemo( - () => - debounce((query: string | undefined) => { - const queryObj = { ...router.query, q: query } - if (!query) delete queryObj.q - router.replace({ query: queryObj }, undefined, { - shallow: true, - }) - }, 100), - [router] - ) + const pushQuery = (query: string | undefined) => { + const history = window.history + const url = withQueryParams(window.location, { q: query }).toString() + history.replaceState({ ...history.state, as: url, url }, '', url) + } const setQuery = (query: string | undefined) => { setQueryState(query) @@ -81,15 +90,15 @@ export function useQueryAndSortParams({ useEffect(() => { // If there's no sort option, then set the one from localstorage - if (router.isReady && !sort && shouldLoadFromStorage) { + if (!sort && shouldLoadFromStorage) { const localSort = localStorage.getItem(MARKETS_SORT) as Sort if (localSort && localSort !== defaultSort) { // Use replace to not break navigating back. - router.replace( - { query: { ...router.query, s: localSort } }, - undefined, - { shallow: true } - ) + const history = window.history + const url = withQueryParams(window.location, { + s: localSort, + }).toString() + history.replaceState({ ...history.state, as: url, url }, '', url) } } })