Skip to content

Commit

Permalink
chore: 🤖 catch up with master
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jan 17, 2020
2 parents 6575b14 + 9439982 commit 973a11f
Show file tree
Hide file tree
Showing 21 changed files with 1,272 additions and 728 deletions.
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
# [13.19.0](https://github.com/streamich/react-use/compare/v13.18.0...v13.19.0) (2020-01-16)


### Features

* add useError hook ([65f3644](https://github.com/streamich/react-use/commit/65f364420524bacebe8f8149b8197fb62bff1a08))

# [13.18.0](https://github.com/streamich/react-use/compare/v13.17.0...v13.18.0) (2020-01-16)


### Bug Fixes

* check for null ([d619c39](https://github.com/streamich/react-use/commit/d619c39a21e9f0b4b4bfc6a209311bf0bd495f9b))


### Features

* add serializer/deserializer option to useLocalStorage ([5316510](https://github.com/streamich/react-use/commit/5316510babf7606a2f4b78de2b0eb85c930890cf))

# [13.17.0](https://github.com/streamich/react-use/compare/v13.16.1...v13.17.0) (2020-01-15)


### Features

* add support for body lock on iOS ([d778408](https://github.com/streamich/react-use/commit/d7784084fe84aca72efe85260101b00ef1df7580))

## [13.16.1](https://github.com/streamich/react-use/compare/v13.16.0...v13.16.1) (2020-01-14)


### Bug Fixes

* update the types dep for js-cookie ([5c55d59](https://github.com/streamich/react-use/commit/5c55d59a7d1d799cba7af87e15ab4a4b27a8fc67))

# [13.16.0](https://github.com/streamich/react-use/compare/v13.15.0...v13.16.0) (2020-01-14)


### Features

* add option to useTitle to restore title on un-mount ([b8b3e47](https://github.com/streamich/react-use/commit/b8b3e479cea6071d4310bac29f138bd8917eee0b))

# [13.15.0](https://github.com/streamich/react-use/compare/v13.14.3...v13.15.0) (2020-01-13)


### Features

* add useCookie hook ([4e5c90f](https://github.com/streamich/react-use/commit/4e5c90f021f56ae2008dc25daad69c43063f608f))

## [13.14.3](https://github.com/streamich/react-use/compare/v13.14.2...v13.14.3) (2020-01-08)


Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@
- [**Side-effects**](./docs/Side-effects.md)
- [`useAsync`](./docs/useAsync.md), [`useAsyncFn`](./docs/useAsyncFn.md), and [`useAsyncRetry`](./docs/useAsyncRetry.md) — resolves an `async` function.
- [`useBeforeUnload`](./docs/useBeforeUnload.md) — shows browser alert when user try to reload or close the page.
- [`useCookie`](./docs/useCookie.md) — provides way to read, update and delete a cookie. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usecookie--demo)
- [`useCopyToClipboard`](./docs/useCopyToClipboard.md) — copies text to clipboard.
- [`useDebounce`](./docs/useDebounce.md) — debounces a function. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usedebounce--demo)
- [`useError`](./docs/useError.md) — error dispatcher. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-useerror--demo)
- [`useFavicon`](./docs/useFavicon.md) — sets favicon of the page.
- [`useLocalStorage`](./docs/useLocalStorage.md) — manages a value in `localStorage`.
- [`useLockBodyScroll`](./docs/useLockBodyScroll.md) — lock scrolling of the body element.
Expand Down Expand Up @@ -150,7 +152,6 @@
- [**Miscellaneous**]()
- [`useEnsuredForwardedRef`](./docs/useEnsuredForwardedRef.md) and [`ensuredForwardRef`](./docs/useEnsuredForwardedRef.md) — use a React.forwardedRef safely. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/state-useensuredforwardedref--demo)


<br />
<br />
<br />
Expand Down
39 changes: 39 additions & 0 deletions docs/useCookie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# `useCookie`

React hook that returns the current value of a `cookie`, a callback to update the `cookie`
and a callback to delete the `cookie.`

## Usage

```jsx
import { useCookie } from "react-use";

const Demo = () => {
const [value, updateCookie, deleteCookie] = useCookie("my-cookie");
const [counter, setCounter] = useState(1);

useEffect(() => {
deleteCookie();
}, []);

const updateCookieHandler = () => {
updateCookie(`my-awesome-cookie-${counter}`);
setCounter(c => c + 1);
};

return (
<div>
<p>Value: {value}</p>
<button onClick={updateCookieHandler}>Update Cookie</button>
<br />
<button onClick={deleteCookie}>Delete Cookie</button>
</div>
);
};
```

## Reference

```ts
const [value, updateCookie, deleteCookie] = useCookie(cookieName: string);
```
34 changes: 34 additions & 0 deletions docs/useError.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# `useError`

React side-effect hook that returns an error dispatcher.

## Usage

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

const Demo = () => {
const dispatchError = useError();

const clickHandler = () => {
dispatchError(new Error('Some error!'));
};

return <button onClick={clickHandler}>Click me to throw</button>;
};

// In parent app
const App = () => (
<ErrorBoundary>
<Demo />
</ErrorBoundary>
);
```

## Reference

```js
const dispatchError = useError();
```

- `dispatchError` &mdash; Callback of type `(err: Error) => void`
13 changes: 9 additions & 4 deletions docs/useLocalStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

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


## Usage

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

const Demo = () => {
const [value, setValue, remove] = useLocalStorage('my-key', 'foo');
Expand All @@ -22,15 +21,21 @@ const Demo = () => {
};
```


## Reference

```js
useLocalStorage(key);
useLocalStorage(key, initialValue);
useLocalStorage(key, initialValue, raw);
useLocalStorage(key, initialValue, { raw: true });
useLocalStorage(key, initialValue, {
raw: false,
serializer: (value: T) => string,
deserializer: (value: string) => T,
});
```

- `key` &mdash; `localStorage` key to manage.
- `initialValue` &mdash; initial value to set, if value in `localStorage` is empty.
- `raw` &mdash; boolean, if set to `true`, hook will not attempt to JSON serialize stored values.
- `serializer` &mdash; custom serializer (defaults to `JSON.stringify`)
- `deserializer` &mdash; custom deserializer (defaults to `JSON.parse`)
32 changes: 18 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@
},
"homepage": "https://github.com/streamich/react-use#readme",
"dependencies": {
"@types/js-cookie": "2.2.4",
"@xobotyi/scrollbar-width": "1.5.0",
"copy-to-clipboard": "^3.2.0",
"fast-shallow-equal": "^1.0.0",
"js-cookie": "^2.2.1",
"nano-css": "^5.2.1",
"react-fast-compare": "^2.0.4",
"react-universal-interface": "^0.6.0",
Expand All @@ -64,22 +66,22 @@
"react-dom": "^16.8.0"
},
"devDependencies": {
"@babel/core": "7.8.0",
"@babel/plugin-syntax-dynamic-import": "7.8.0",
"@babel/preset-env": "7.8.0",
"@babel/preset-react": "7.8.0",
"@babel/preset-typescript": "7.8.0",
"@babel/core": "7.8.3",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/preset-env": "7.8.3",
"@babel/preset-react": "7.8.3",
"@babel/preset-typescript": "7.8.3",
"@semantic-release/changelog": "3.0.6",
"@semantic-release/git": "7.0.18",
"@semantic-release/npm": "5.3.5",
"@shopify/jest-dom-mocks": "2.8.8",
"@storybook/addon-actions": "5.3.1",
"@storybook/addon-knobs": "5.3.1",
"@storybook/addon-notes": "5.3.1",
"@storybook/addon-options": "5.3.1",
"@storybook/react": "5.3.1",
"@storybook/addon-actions": "5.3.5",
"@storybook/addon-knobs": "5.3.5",
"@storybook/addon-notes": "5.3.5",
"@storybook/addon-options": "5.3.5",
"@storybook/react": "5.3.5",
"@testing-library/react-hooks": "3.2.1",
"@types/jest": "24.0.25",
"@types/jest": "24.9.0",
"@types/react": "16.9.11",
"babel-core": "6.26.3",
"babel-loader": "8.0.6",
Expand All @@ -88,6 +90,7 @@
"gh-pages": "2.2.0",
"husky": "3.1.0",
"jest": "24.9.0",
"jest-localstorage-mock": "2.4.0",
"keyboardjs": "2.5.1",
"lint-staged": "9.5.0",
"markdown-loader": "5.1.0",
Expand All @@ -106,13 +109,13 @@
"semantic-release": "15.14.0",
"ts-jest": "24.3.0",
"ts-loader": "6.2.1",
"ts-node": "8.6.1",
"ts-node": "8.6.2",
"tslint": "6.0.0-beta1",
"tslint-config-prettier": "1.18.0",
"tslint-eslint-rules": "5.4.0",
"tslint-plugin-prettier": "2.1.0",
"tslint-react": "4.1.0",
"typescript": "3.7.4"
"typescript": "3.7.5"
},
"config": {
"commitizen": {
Expand Down Expand Up @@ -160,7 +163,8 @@
"<rootDir>/tests/**/*.test.(ts|tsx)"
],
"setupFiles": [
"<rootDir>/tests/_setup.js"
"<rootDir>/tests/_setup.js",
"./tests/setupTests.ts"
]
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { default as useBattery } from './useBattery';
export { default as useBeforeUnload } from './useBeforeUnload';
export { default as useBoolean } from './useBoolean';
export { default as useClickAway } from './useClickAway';
export { default as useCookie } from './useCookie';
export { default as useCopyToClipboard } from './useCopyToClipboard';
export { default as useCounter } from './useCounter';
export { default as useCss } from './useCss';
Expand All @@ -20,6 +21,7 @@ export { default as useDropArea } from './useDropArea';
export { default as useEffectOnce } from './useEffectOnce';
export { default as useEnsuredForwardedRef, ensuredForwardRef } from './useEnsuredForwardedRef';
export { default as useEvent } from './useEvent';
export { default as useError } from './useError';
export { default as useFavicon } from './useFavicon';
export { default as useFullscreen } from './useFullscreen';
export { default as useGeolocation } from './useGeolocation';
Expand Down
25 changes: 25 additions & 0 deletions src/useCookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useState, useCallback } from 'react';
import Cookies from 'js-cookie';

const useCookie = (
cookieName: string
): [string | null, (newValue: string, options?: Cookies.CookieAttributes) => void, () => void] => {
const [value, setValue] = useState<string | null>(() => Cookies.get(cookieName) || null);

const updateCookie = useCallback(
(newValue: string, options?: Cookies.CookieAttributes) => {
Cookies.set(cookieName, newValue, options);
setValue(newValue);
},
[cookieName]
);

const deleteCookie = useCallback(() => {
Cookies.remove(cookieName);
setValue(null);
}, [cookieName]);

return [value, updateCookie, deleteCookie];
};

export default useCookie;
19 changes: 19 additions & 0 deletions src/useError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useState, useEffect, useCallback } from 'react';

const useError = (): ((err: Error) => void) => {
const [error, setError] = useState<Error | null>(null);

useEffect(() => {
if (error) {
throw error;
}
}, [error]);

const dispatchError = useCallback((err: Error) => {
setError(err);
}, []);

return dispatchError;
};

export default useError;
32 changes: 20 additions & 12 deletions src/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
import { useEffect, useState, useCallback } from 'react';
import { isClient } from './util';

type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);
type parserOptions<T> =
| {
raw: true;
}
| {
raw: false;
serializer: (value: T) => string;
deserializer: (value: string) => T;
};

const noop = () => {};
const isUndefined = (value?: any): boolean => typeof value === 'undefined';

const useLocalStorage = <T>(
key: string,
initialValue?: T,
raw?: boolean
): [T | undefined, Dispatch<SetStateAction<T | undefined>>, () => void] => {
options?: parserOptions<T>
): [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>, () => void] => {
if (!isClient) {
return [initialValue as T, noop, noop];
}

// Use provided serializer/deserializer or the default ones
const serializer = options ? (options.raw ? String : options.serializer) : JSON.stringify;
const deserializer = options ? (options.raw ? String : options.deserializer) : JSON.parse;

const [state, setState] = useState<T | undefined>(() => {
try {
const localStorageValue = localStorage.getItem(key);
if (isUndefined(initialValue)) {
return undefined;
}
if (typeof localStorageValue !== 'string') {
localStorage.setItem(key, raw ? String(initialValue) : JSON.stringify(initialValue));
if (localStorageValue !== null) {
return deserializer(localStorageValue);
} else {
initialValue && localStorage.setItem(key, serializer(initialValue));
return initialValue;
}
return raw ? localStorageValue : JSON.parse(localStorageValue || 'null');
} catch {
// If user is in private mode or has storage restriction
// localStorage can throw. JSON.parse and JSON.stringify
Expand All @@ -48,8 +57,7 @@ const useLocalStorage = <T>(
useEffect(() => {
if (isUndefined(state)) return;
try {
const serializedState = raw ? String(state) : JSON.stringify(state);
localStorage.setItem(key, serializedState);
localStorage.setItem(key, serializer(state));
} catch {
// If user is in private mode or has storage restriction
// localStorage can throw. Also JSON.stringify can throw.
Expand Down
Loading

0 comments on commit 973a11f

Please sign in to comment.