diff --git a/docs/useToggle.md b/docs/useToggle.md
index 93a4e4ec3b..e1a342e76a 100644
--- a/docs/useToggle.md
+++ b/docs/useToggle.md
@@ -4,7 +4,6 @@ React state hook that tracks value of a boolean.
`useBoolean` is an alias for `useToggle`.
-
## Usage
```jsx
@@ -16,7 +15,7 @@ const Demo = () => {
return (
{on ? 'ON' : 'OFF'}
-
toggle()}>Toggle
+
Toggle
toggle(true)}>set ON
toggle(false)}>set OFF
diff --git a/src/__stories__/useToggle.story.tsx b/src/__stories__/useToggle.story.tsx
index c14397534c..0b937d24de 100644
--- a/src/__stories__/useToggle.story.tsx
+++ b/src/__stories__/useToggle.story.tsx
@@ -9,7 +9,7 @@ const Demo = () => {
return (
{on ? 'ON' : 'OFF'}
-
toggle()}>Toggle
+
Toggle
toggle(true)}>set ON
toggle(false)}>set OFF
diff --git a/src/__tests__/useToggle.test.tsx b/src/__tests__/useToggle.test.tsx
new file mode 100644
index 0000000000..bcf1d78f58
--- /dev/null
+++ b/src/__tests__/useToggle.test.tsx
@@ -0,0 +1,49 @@
+import { act, cleanup, renderHook } from 'react-hooks-testing-library';
+import useToggle from '../useToggle';
+
+afterEach(cleanup);
+
+describe('useToggle', () => {
+ it('should be defined', () => {
+ expect(useToggle).toBeDefined();
+ });
+
+ const hook = renderHook(props => useToggle(props), { initialProps: false });
+
+ it('should return initial state on initial render', () => {
+ expect(hook.result.current[0]).toBe(false);
+ });
+
+ it('should update state with correct value', () => {
+ hook.rerender(true);
+ expect(hook.result.current[0]).toBe(true);
+
+ act(() => {
+ hook.result.current[1](false);
+ });
+
+ expect(hook.result.current[0]).toBe(false);
+ });
+
+ // it('should toggle state without a value parameter', () => {
+ // act(() => {
+ // hook.result.current[1]();
+ // });
+
+ // expect(hook.result.current[0]).toBe(true);
+ // });
+
+ // it('should ignore non-boolean parameters', () => {
+ // act(() => {
+ // hook.result.current[1]('string');
+ // });
+
+ // expect(hook.result.current[0]).toBe(true);
+
+ // act(() => {
+ // hook.result.current[1]({});
+ // });
+
+ // expect(hook.result.current[0]).toBe(false);
+ // });
+});
diff --git a/src/useToggle.ts b/src/useToggle.ts
index 793257143f..b3b7ab1f28 100644
--- a/src/useToggle.ts
+++ b/src/useToggle.ts
@@ -1,23 +1,15 @@
import { useCallback, useState } from 'react';
-export type UseToggle = (
- state: boolean
-) => [
- boolean, // state
- (nextValue?: boolean) => void // toggle
-];
-
-const useToggle: UseToggle = state => {
- const [value, setValue] = useState(state);
+const useToggle = (initialValue: boolean): [boolean, (nextValue?: any) => void] => {
+ const [value, setValue] = useState(initialValue);
const toggle = useCallback(
- (nextValue?: boolean) => {
- if (typeof nextValue !== 'undefined') {
- setValue(!!nextValue);
- return;
+ (nextValue?: any) => {
+ if (typeof nextValue === 'boolean') {
+ setValue(nextValue);
+ } else {
+ setValue(currentValue => !currentValue);
}
-
- setValue(newValue => !newValue);
},
[setValue]
);