-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(useCounter): add docs and tests (#7828)
- Делаем возврат функции useCounter похожим на useState - Добавляем документацию - Добавляем тестов
- Loading branch information
1 parent
0f3f9db
commit 9c0f507
Showing
3 changed files
with
129 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { act } from 'react'; | ||
import { renderHook } from '@testing-library/react'; | ||
import { useCounter } from './useCounter'; | ||
|
||
describe('useCounter', () => { | ||
it('returns default value', () => { | ||
const { result } = renderHook(useCounter); | ||
expect(result.current[0]).toEqual(0); | ||
}); | ||
|
||
it('returns passed value with initialProps number', () => { | ||
const { result } = renderHook(useCounter, { | ||
initialProps: 99, | ||
}); | ||
expect(result.current[0]).toEqual(99); | ||
}); | ||
it('returns passed value with initialProps function', () => { | ||
const { result } = renderHook(useCounter, { | ||
initialProps: () => 99, | ||
}); | ||
expect(result.current[0]).toEqual(99); | ||
}); | ||
|
||
it('increment value', () => { | ||
const { result } = renderHook(useCounter); | ||
act(() => { | ||
result.current[1].increment(); | ||
result.current[1].increment(); | ||
}); | ||
expect(result.current[0]).toEqual(2); | ||
}); | ||
it('increment value with delta', () => { | ||
const { result } = renderHook(useCounter); | ||
act(() => { | ||
result.current[1].increment(5); | ||
result.current[1].increment(5); | ||
}); | ||
expect(result.current[0]).toEqual(10); | ||
}); | ||
|
||
it('decrement value', () => { | ||
const { result } = renderHook(useCounter); | ||
act(() => { | ||
result.current[1].decrement(); | ||
result.current[1].decrement(); | ||
}); | ||
expect(result.current[0]).toEqual(-2); | ||
}); | ||
it('decrement value with delta', () => { | ||
const { result } = renderHook(useCounter); | ||
act(() => { | ||
result.current[1].decrement(5); | ||
result.current[1].decrement(5); | ||
}); | ||
expect(result.current[0]).toEqual(-10); | ||
}); | ||
|
||
it('setCount value', () => { | ||
const { result } = renderHook(useCounter); | ||
act(() => { | ||
result.current[1].setCount(5); | ||
}); | ||
expect(result.current[0]).toEqual(5); | ||
}); | ||
|
||
it('actions not change after re-render', () => { | ||
const { result } = renderHook(useCounter); | ||
const firstRenderActions = result.current[1]; | ||
|
||
act(() => { | ||
result.current[1].increment(); | ||
}); | ||
|
||
expect(result.current[1]).toEqual(firstRenderActions); | ||
expect(result.current[1].increment).toEqual(firstRenderActions.increment); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,61 @@ | ||
import * as React from 'react'; | ||
|
||
type UseCounterReturn = { | ||
count: number; | ||
increment: () => void; | ||
decrement: () => void; | ||
type Actions = { | ||
/** | ||
* Увеличивает значение счетчика и вызывает ре-рендер | ||
* | ||
* @param delta Значение на которое требуется увеличить счетчик. По умолчанию `1` | ||
*/ | ||
increment: (delta?: number) => void; | ||
/** | ||
* Уменьшает значение счетчика и вызывает ре-рендер | ||
* | ||
* @param delta Значение на которое требуется увеличить счетчик. По умолчанию `1` | ||
*/ | ||
decrement: (delta?: number) => void; | ||
|
||
/** | ||
* Функция, позволяющая обновить значение счетчика и вызвать ре-рендер | ||
*/ | ||
setCount: React.Dispatch<React.SetStateAction<number>>; | ||
}; | ||
|
||
/** | ||
* Хук счетчика с возможностью задания начального значения и увеличения/уменьшения на 1. | ||
* Хук счетчика с возможностью задания начального значения и увеличения/уменьшения значения. | ||
* | ||
* @param initialValue начальное значение счетчика. По умолчанию `0` | ||
* | ||
* ## Пример | ||
* | ||
* ```js | ||
* const Component = () => { | ||
* const [count, { increment, decrement, setCount }] = useCounter(0); | ||
* | ||
* return ( | ||
* <div> | ||
* <div>count: {count}</div> | ||
* | ||
* <button onClick={() => increment()}> +1 </button> | ||
* <button onClick={() => decrement()}> -1 </button> | ||
* <button onClick={() => increment(5)}> +5 </button> | ||
* <button onClick={() => decrement(5)}> -5 </button> | ||
* <button onClick={() => setCount(0)}> set 0 </button> | ||
* </div> | ||
* ); | ||
* } | ||
* ``` | ||
*/ | ||
export function useCounter(initialValue: number | (() => number) = 0): UseCounterReturn { | ||
export function useCounter(initialValue: number | (() => number) = 0): [number, Actions] { | ||
const [count, setCount] = React.useState(initialValue); | ||
|
||
const increment = React.useCallback(() => setCount((x) => x + 1), []); | ||
|
||
const decrement = React.useCallback(() => setCount((x) => x - 1), []); | ||
const actions = React.useMemo( | ||
() => ({ | ||
increment: (delta = 1) => setCount((x) => x + delta), | ||
decrement: (delta = 1) => setCount((x) => x - delta), | ||
setCount, | ||
}), | ||
[], | ||
); | ||
|
||
return { | ||
count, | ||
increment, | ||
decrement, | ||
setCount, | ||
}; | ||
return [count, actions]; | ||
} |