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;