diff --git a/site/src/components/Filter/filter.tsx b/site/src/components/Filter/filter.tsx index 4ed99cb875037..f3312ea862eb5 100644 --- a/site/src/components/Filter/filter.tsx +++ b/site/src/components/Filter/filter.tsx @@ -26,7 +26,6 @@ import Divider from "@mui/material/Divider"; import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined"; import { useDebouncedFunction } from "hooks/debounce"; -import { useEffectEvent } from "hooks/hookPolyfills"; export type PresetFilter = { name: string; @@ -56,26 +55,6 @@ export const useFilter = ({ const [searchParams, setSearchParams] = searchParamsResult; const query = searchParams.get(useFilterParamsKey) ?? fallbackFilter; - // Stabilizing reference to setSearchParams from one central spot, just to be - // on the extra careful side; don't want effects over-running. You would think - // this would be overkill, but setSearchParams isn't stable out of the box - const stableSetSearchParams = useEffectEvent(setSearchParams); - - // Keep params synced with query, even as query changes from outside sources - useEffect(() => { - stableSetSearchParams((currentParams) => { - const currentQuery = currentParams.get(useFilterParamsKey); - - if (query === "") { - currentParams.delete(useFilterParamsKey); - } else if (currentQuery !== query) { - currentParams.set(useFilterParamsKey, query); - } - - return currentParams; - }); - }, [stableSetSearchParams, query]); - const update = (newValues: string | FilterValues) => { const serialized = typeof newValues === "string" ? newValues : stringifyFilter(newValues); diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx index 9bafa75e6d9b0..5273cd2f4486f 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPage.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPage.tsx @@ -4,7 +4,7 @@ import { useDashboard, useIsWorkspaceActionsEnabled, } from "components/Dashboard/DashboardProvider"; -import { type FC, useEffect, useState, useSyncExternalStore } from "react"; +import { type FC, useEffect, useState } from "react"; import { Helmet } from "react-helmet-async"; import { pageTitle } from "utils/page"; import { useWorkspacesData, useWorkspaceUpdate } from "./data"; @@ -140,29 +140,6 @@ const WorkspacesPage: FC = () => { export default WorkspacesPage; -const workspaceFilterKey = "WorkspacesPage/filter"; -const defaultWorkspaceFilter = "owner:me"; - -// Function should stay outside components as much as possible; if declared -// inside the component, React would add/remove event listeners every render -function subscribeToFilterChanges(notifyReact: () => void) { - const onStorageChange = (event: StorageEvent) => { - const { key, storageArea, oldValue, newValue } = event; - - const shouldNotify = - key === workspaceFilterKey && - storageArea === window.localStorage && - newValue !== oldValue; - - if (shouldNotify) { - notifyReact(); - } - }; - - window.addEventListener("storage", onStorageChange); - return () => window.removeEventListener("storage", onStorageChange); -} - type UseWorkspacesFilterOptions = { searchParamsResult: ReturnType; onFilterChange: () => void; @@ -172,27 +149,10 @@ const useWorkspacesFilter = ({ searchParamsResult, onFilterChange, }: UseWorkspacesFilterOptions) => { - // Using useSyncExternalStore store to safely access localStorage from the - // first render; both snapshot callbacks return primitives, so no special - // trickery needed to prevent hook from immediately blowing up in dev mode - const localStorageFilter = useSyncExternalStore( - subscribeToFilterChanges, - () => { - return ( - window.localStorage.getItem(workspaceFilterKey) ?? - defaultWorkspaceFilter - ); - }, - () => defaultWorkspaceFilter, - ); - const filter = useFilter({ - fallbackFilter: localStorageFilter, + fallbackFilter: "owner:me", searchParamsResult, - onUpdate: (newValues) => { - window.localStorage.setItem(workspaceFilterKey, newValues); - onFilterChange(); - }, + onUpdate: onFilterChange, }); const permissions = usePermissions();