Skip to content

Commit

Permalink
feat: add useSessionStorage hook
Browse files Browse the repository at this point in the history
* Add useSessionStorage

* chore: uncomment session storage docs story
  • Loading branch information
ajoslin authored and streamich committed Nov 6, 2018
1 parent 58532f7 commit eca432a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
- [`useCss`](./docs/useCss.md) — dynamically adjusts CSS.
- [`useFavicon`](./docs/useFavicon.md) — sets favicon of the page.
- [`useLocalStorage`](./docs/useLocalStorage.md) — manages a value in `localStorage`.
- [`useSessionStorage`](./docs/useSessionStorage.md) — manages a value in `sessionStorage`.
- [`useTitle`](./docs/useTitle.md) — sets title of the page.
<br/>
<br/>
Expand Down
35 changes: 35 additions & 0 deletions docs/useSessionStorage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# `useSessionStorage`

React side-effect hook that manages a single `sessionStorage` key.


## Usage

```jsx
import {useSessionStorage} from 'react-use';

const Demo = () => {
const [value, setValue] = useSessionStorage('my-key', 'foo');

return (
<div>
<div>Value: {value}</div>
<button onClick={() => setValue('bar')}>bar</button>
<button onClick={() => setValue('baz')}>baz</button>
</div>
);
};
```


## Reference

```js
useSessionStorage(key);
useSessionStorage(key, initialValue);
useSessionStorage(key, initialValue, raw);
```

- `key` &mdash; `sessionStorage` key to manage.
- `initialValue` &mdash; initial value to set, if value in `sessionStorage` is empty.
- `raw` &mdash; boolean, if set to `true`, hook will not attempt to JSON serialize stored values.
21 changes: 21 additions & 0 deletions src/__stories__/useSessionStorage.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {storiesOf} from '@storybook/react';
import * as React from 'react';
import {useSessionStorage} from '..';

const Demo = () => {
const [value, setValue] = useSessionStorage('hello-key', 'foo');

return (
<div>
<div>Value: {value}</div>
<button onClick={() => setValue('bar')}>bar</button>
<button onClick={() => setValue('baz')}>baz</button>
</div>
);
};

storiesOf('useSessionStorage', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useSessionStorage.md')} />)
.add('Demo', () =>
<Demo/>
)
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import useOrientation from './useOrientation';
import useOutsideClick from './useOutsideClick';
import useRaf from './useRaf';
import useRenderProp from './useRenderProp';
import useSessionStorage from './useSessionStorage';
import useSetState from './useSetState';
import useSize from './useSize';
import useSpeech from './useSpeech';
Expand Down Expand Up @@ -78,6 +79,7 @@ export {
useOutsideClick,
useRaf,
useRenderProp,
useSessionStorage,
useSetState,
useSize,
useSpeech,
Expand Down
40 changes: 40 additions & 0 deletions src/useSessionStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {useState, useEffect} from './react';

const isClient = typeof window === 'object';

const useSessionStorage = <T>(key: string, initialValue?: T, raw?: boolean): [T, (value: T) => void] => {
if (!isClient) {
return [initialValue as T, () => {}];
}

const [state, setState] = useState<T>(() => {
try {
const sessionStorageValue = sessionStorage.getItem(key);
if (typeof sessionStorageValue !== 'string') {
sessionStorage.setItem(key, raw ? String(initialValue) : JSON.stringify(initialValue));
return initialValue;
} else {
return raw ? sessionStorageValue : JSON.parse(sessionStorageValue || 'null');
}
} catch {
// If user is in private mode or has storage restriction
// sessionStorage can throw. JSON.parse and JSON.stringify
// cat throw, too.
return initialValue;
}
});

useEffect(() => {
try {
const serializedState = raw ? String(state) : JSON.stringify(state);
sessionStorage.setItem(key, serializedState);
} catch {
// If user is in private mode or has storage restriction
// sessionStorage can throw. Also JSON.stringify can throw.
}
});

return [state, setState];
};

export default useSessionStorage;

0 comments on commit eca432a

Please sign in to comment.