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'}
- +
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'}
- +
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] );