From b22f32f6f6f7fcf3377df59478765785d3c1300b Mon Sep 17 00:00:00 2001 From: streamich Date: Sun, 1 Sep 2019 22:21:14 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20useSearchParam()?= =?UTF-8?q?=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__stories__/useSearchParam.story.tsx | 27 ++++++++++++++++++++++ src/index.ts | 1 + src/useSearchParam.ts | 29 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/__stories__/useSearchParam.story.tsx create mode 100644 src/useSearchParam.ts diff --git a/src/__stories__/useSearchParam.story.tsx b/src/__stories__/useSearchParam.story.tsx new file mode 100644 index 0000000000..dc6cbb5466 --- /dev/null +++ b/src/__stories__/useSearchParam.story.tsx @@ -0,0 +1,27 @@ +import { storiesOf } from '@storybook/react'; +import * as React from 'react'; +import { useSearchParam } from '..'; +import ShowDocs from './util/ShowDocs'; + +const Demo = () => { + const foo = useSearchParam('foo'); + + return ( +
+
foo: {foo || '🤷‍♂️'}
+
+ +
+
+ +
+
+ +
+
+ ); +}; + +storiesOf('Sensors|useSearchParam', module) + // .add('Docs', () => ) + .add('Demo', () => ); diff --git a/src/index.ts b/src/index.ts index 9fc6319435..74a7dd311e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,6 +63,7 @@ export { default as useRafLoop } from './useRafLoop'; * @deprecated This hook is obsolete, use `useMountedState` instead */ export { default as useRefMounted } from './useRefMounted'; +export { default as useSearchParam } from './useSearchParam'; export { default as useScroll } from './useScroll'; export { default as useScrolling } from './useScrolling'; export { default as useSessionStorage } from './useSessionStorage'; diff --git a/src/useSearchParam.ts b/src/useSearchParam.ts new file mode 100644 index 0000000000..b7107e3f32 --- /dev/null +++ b/src/useSearchParam.ts @@ -0,0 +1,29 @@ +import { useState, useEffect } from 'react'; + +const getValue = (search: string, param: string) => new URLSearchParams(search).get(param); + +export type UseQueryParam = (param: string) => string | null; + +const useSearchParam: UseQueryParam = param => { + const [value, setValue] = useState(() => getValue(location.search, param)); + + useEffect(() => { + const onChange = () => { + setValue(getValue(location.search, param)); + }; + + window.addEventListener('popstate', onChange); + window.addEventListener('pushstate', onChange); + window.addEventListener('replacestate', onChange); + + return () => { + window.removeEventListener('popstate', onChange); + window.removeEventListener('pushstate', onChange); + window.removeEventListener('replacestate', onChange); + }; + }, []); + + return value; +}; + +export default useSearchParam;