diff --git a/README.md b/README.md
index 53b9fa46..db966005 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,7 @@
- [**State**](./docs/State.md)
- [`useGetSet`](./docs/useGetSet.md) — returns state getter `get()` instead of raw state.
+ - [`useGetSetState`](./docs/useGetSetState.md) — as if [`useGetSet`](./docs/useGetSet.md) and [`useSetState`](./docs/useSetState.md) had a baby.
- [`useObservable`](./docs/useObservable.md) — tracks latest value of an `Observable`.
- [`useSetState`](./docs/useSetState.md) — creates `setState` method which works like `this.setState`. [![][img-demo]](https://codesandbox.io/s/n75zqn1xp0)
- [`useToggle` and `useBoolean`](./docs/useToggle.md) — tracks state of a boolean.
diff --git a/docs/useGetSetState.md b/docs/useGetSetState.md
new file mode 100644
index 00000000..059e00be
--- /dev/null
+++ b/docs/useGetSetState.md
@@ -0,0 +1,23 @@
+# `useGetSetState`
+
+A mix of `useGetSet` and `useGetSetState`.
+
+
+## Usage
+
+```jsx
+import {useGetSetState} from 'react-use';
+
+const Demo = () => {
+ const [get, setState] = useGetSetState({cnt: 0});
+ const onClick = () => {
+ setTimeout(() => {
+ setState({cnt: get().cnt + 1})
+ }, 1_000);
+ };
+
+ return (
+
+ );
+};
+```
diff --git a/src/__stories__/useGetSetState.story.tsx b/src/__stories__/useGetSetState.story.tsx
new file mode 100644
index 00000000..15971bea
--- /dev/null
+++ b/src/__stories__/useGetSetState.story.tsx
@@ -0,0 +1,23 @@
+import * as React from 'react';
+import {storiesOf} from '@storybook/react';
+import {useGetSetState, useSetState} from '..';
+import ShowDocs from '../util/ShowDocs';
+
+const Demo = () => {
+ const [get, setState] = useGetSetState<{cnt: number}>({cnt: 0});
+ const onClick = () => {
+ setTimeout(() => {
+ setState({cnt: get().cnt + 1})
+ }, 1_000);
+ };
+
+ return (
+
+ );
+};
+
+storiesOf('useGetSetState', module)
+ .add('Docs', () => )
+ .add('Demo', () =>
+
+ )
diff --git a/src/index.ts b/src/index.ts
index 00a5e597..b32ad71a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -7,6 +7,7 @@ import useCss from './useCss';
import useFavicon from './useFavicon';
import useGeolocation from './useGeolocation';
import useGetSet from './useGetSet';
+import useGetSetState from './useGetSetState';
import useHover from './useHover';
import useIdle from './useIdle';
import useLifecycles from './useLifecycles';
@@ -45,6 +46,7 @@ export {
useFavicon,
useGeolocation,
useGetSet,
+ useGetSetState,
useHover,
useIdle,
useLifecycles,
diff --git a/src/useAudio.ts b/src/useAudio.ts
index 50a8e5da..f0df39a3 100644
--- a/src/useAudio.ts
+++ b/src/useAudio.ts
@@ -48,7 +48,7 @@ const useAudio = (props: AudioProps): [React.ReactElement, AudioStat
const onPlay = () => setState({isPlaying: true});
const onPause = () => setState({isPlaying: false});
- const onVolumeChange = (event) => {
+ const onVolumeChange = () => {
const el = ref.current;
if (!el) return;
setState({
@@ -56,7 +56,7 @@ const useAudio = (props: AudioProps): [React.ReactElement, AudioStat
volume: el.volume,
});
};
- const onDurationChange = (event) => {
+ const onDurationChange = () => {
const el = ref.current;
if (!el) return;
const {duration, buffered} = el;
@@ -70,7 +70,7 @@ const useAudio = (props: AudioProps): [React.ReactElement, AudioStat
if (!el) return;
setState({time: el.currentTime});
};
- const onProgress = (event) => {
+ const onProgress = () => {
const el = ref.current;
if (!el) return;
setState({buffered: parseTimeRanges(el.buffered)});
@@ -102,7 +102,7 @@ const useAudio = (props: AudioProps): [React.ReactElement, AudioStat
if (!lockPlay) {
const promise = el.play();
const isPromise = typeof promise === 'object';
-
+
if (isPromise) {
lockPlay = true;
const resetLock = () => {
@@ -152,14 +152,14 @@ const useAudio = (props: AudioProps): [React.ReactElement, AudioStat
if (!el) {
if (process.env.NODE_ENV !== 'production') {
console.error(
- 'useAudio() ref to