diff --git a/src/useSearchParam.ts b/src/useSearchParam.ts index 64440d200e..592145ac71 100644 --- a/src/useSearchParam.ts +++ b/src/useSearchParam.ts @@ -14,6 +14,8 @@ const useSearchParam: UseQueryParam = (param) => { setValue(getValue(location.search, param)); }; + onChange(); + on(window, 'popstate', onChange); on(window, 'pushstate', onChange); on(window, 'replacestate', onChange); @@ -23,7 +25,7 @@ const useSearchParam: UseQueryParam = (param) => { off(window, 'pushstate', onChange); off(window, 'replacestate', onChange); }; - }, []); + }, [param]); return value; }; diff --git a/tests/useSearchParam.test.ts b/tests/useSearchParam.test.ts index d3be101631..2e9a947ed2 100644 --- a/tests/useSearchParam.test.ts +++ b/tests/useSearchParam.test.ts @@ -35,6 +35,38 @@ it('returns null if search param not found', () => { expect(result.current).toBe(null); }); +it('reads the new parameter when its name changes', () => { + mockSearch = 'foo=bar&baz=quux'; + const { result, rerender } = renderHook(({ param }) => useSearchParam(param), { + initialProps: { param: 'foo' }, + }); + + rerender({ param: 'baz' }); + expect(result.current).toBe('quux'); + + rerender({ param: 'missing' }); + expect(result.current).toBe(null); +}); + +it.each(['popstate', 'pushstate', 'replacestate'])( + 'tracks the new parameter on %s after its name changes', + (event) => { + mockSearch = 'foo=bar&baz=quux'; + const { result, rerender, unmount } = renderHook(({ param }) => useSearchParam(param), { + initialProps: { param: 'foo' }, + }); + + rerender({ param: 'baz' }); + act(() => { + mockSearch = 'foo=1&baz=2'; + window.dispatchEvent(new Event(event)); + }); + + expect(result.current).toBe('2'); + unmount(); + } +); + it('tracks the latest search param value', () => { mockSearch = 'foo=bar&baz=quux';