From 7d74e09f6361855dcfb75397e15e68ef74ccc2a1 Mon Sep 17 00:00:00 2001 From: Julien Date: Fri, 9 Feb 2024 12:54:24 +0100 Subject: [PATCH] Docs/add use event callback documentation (#481) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 📝 Add docs for `useEventCallback` * 📝 Add demo for `useEventCallback` * ✅ Add unit tests for `useEventCallback` * ✏️ Remove useless comment in useLocalStorage's demo * 🔖 Add changeset * 📝 Update README --- .changeset/dry-deers-listen.md | 5 ++++ README.md | 4 +-- packages/usehooks-ts/README.md | 4 +-- .../useEventCallback.demo.tsx | 10 ++++++++ .../src/useEventCallback/useEventCallback.md | 22 ++++++++++++++++ .../useEventCallback.test.tsx | 25 +++++++++++++++++++ .../src/useEventCallback/useEventCallback.ts | 1 + .../useLocalStorage/useLocalStorage.demo.tsx | 1 - 8 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 .changeset/dry-deers-listen.md create mode 100644 packages/usehooks-ts/src/useEventCallback/useEventCallback.demo.tsx create mode 100644 packages/usehooks-ts/src/useEventCallback/useEventCallback.md create mode 100644 packages/usehooks-ts/src/useEventCallback/useEventCallback.test.tsx diff --git a/.changeset/dry-deers-listen.md b/.changeset/dry-deers-listen.md new file mode 100644 index 00000000..9f68e69d --- /dev/null +++ b/.changeset/dry-deers-listen.md @@ -0,0 +1,5 @@ +--- +"usehooks-ts": patch +--- + +Release documentation for `useEventCallback` diff --git a/README.md b/README.md index 9d5df564..7fd4205e 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,12 @@ - [`useDebounceCallback()`](https://usehooks-ts.com/react-hook/use-debounce-callback) - [`useDebounceValue()`](https://usehooks-ts.com/react-hook/use-debounce-value) - [`useDocumentTitle()`](https://usehooks-ts.com/react-hook/use-document-title) -- [`useEffectOnce()`](https://usehooks-ts.com/react-hook/use-effect-once) +- [`useEventCallback()`](https://usehooks-ts.com/react-hook/use-event-callback) - [`useEventListener()`](https://usehooks-ts.com/react-hook/use-event-listener) - [`useHover()`](https://usehooks-ts.com/react-hook/use-hover) - [`useIntersectionObserver()`](https://usehooks-ts.com/react-hook/use-intersection-observer) - [`useInterval()`](https://usehooks-ts.com/react-hook/use-interval) - [`useIsClient()`](https://usehooks-ts.com/react-hook/use-is-client) -- [`useIsFirstRender()`](https://usehooks-ts.com/react-hook/use-is-first-render) - [`useIsMounted()`](https://usehooks-ts.com/react-hook/use-is-mounted) - [`useIsomorphicLayoutEffect()`](https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect) - [`useLocalStorage()`](https://usehooks-ts.com/react-hook/use-local-storage) @@ -68,7 +67,6 @@ - [`useTimeout()`](https://usehooks-ts.com/react-hook/use-timeout) - [`useToggle()`](https://usehooks-ts.com/react-hook/use-toggle) - [`useUnmount()`](https://usehooks-ts.com/react-hook/use-unmount) -- [`useUpdateEffect()`](https://usehooks-ts.com/react-hook/use-update-effect) - [`useWindowSize()`](https://usehooks-ts.com/react-hook/use-window-size) diff --git a/packages/usehooks-ts/README.md b/packages/usehooks-ts/README.md index 9d5df564..7fd4205e 100644 --- a/packages/usehooks-ts/README.md +++ b/packages/usehooks-ts/README.md @@ -44,13 +44,12 @@ - [`useDebounceCallback()`](https://usehooks-ts.com/react-hook/use-debounce-callback) - [`useDebounceValue()`](https://usehooks-ts.com/react-hook/use-debounce-value) - [`useDocumentTitle()`](https://usehooks-ts.com/react-hook/use-document-title) -- [`useEffectOnce()`](https://usehooks-ts.com/react-hook/use-effect-once) +- [`useEventCallback()`](https://usehooks-ts.com/react-hook/use-event-callback) - [`useEventListener()`](https://usehooks-ts.com/react-hook/use-event-listener) - [`useHover()`](https://usehooks-ts.com/react-hook/use-hover) - [`useIntersectionObserver()`](https://usehooks-ts.com/react-hook/use-intersection-observer) - [`useInterval()`](https://usehooks-ts.com/react-hook/use-interval) - [`useIsClient()`](https://usehooks-ts.com/react-hook/use-is-client) -- [`useIsFirstRender()`](https://usehooks-ts.com/react-hook/use-is-first-render) - [`useIsMounted()`](https://usehooks-ts.com/react-hook/use-is-mounted) - [`useIsomorphicLayoutEffect()`](https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect) - [`useLocalStorage()`](https://usehooks-ts.com/react-hook/use-local-storage) @@ -68,7 +67,6 @@ - [`useTimeout()`](https://usehooks-ts.com/react-hook/use-timeout) - [`useToggle()`](https://usehooks-ts.com/react-hook/use-toggle) - [`useUnmount()`](https://usehooks-ts.com/react-hook/use-unmount) -- [`useUpdateEffect()`](https://usehooks-ts.com/react-hook/use-update-effect) - [`useWindowSize()`](https://usehooks-ts.com/react-hook/use-window-size) diff --git a/packages/usehooks-ts/src/useEventCallback/useEventCallback.demo.tsx b/packages/usehooks-ts/src/useEventCallback/useEventCallback.demo.tsx new file mode 100644 index 00000000..fb4ea4ac --- /dev/null +++ b/packages/usehooks-ts/src/useEventCallback/useEventCallback.demo.tsx @@ -0,0 +1,10 @@ +import { useEventCallback } from './useEventCallback' + +export default function Component() { + const handleClick = useEventCallback(event => { + // Handle the event here + console.log('Clicked', event) + }) + + return +} diff --git a/packages/usehooks-ts/src/useEventCallback/useEventCallback.md b/packages/usehooks-ts/src/useEventCallback/useEventCallback.md new file mode 100644 index 00000000..1a5ebcfb --- /dev/null +++ b/packages/usehooks-ts/src/useEventCallback/useEventCallback.md @@ -0,0 +1,22 @@ +The `useEventCallback` hook is a utility for creating memoized event callback functions in React applications. It ensures that the provided callback function is memoized and stable across renders, while also preventing its invocation during the render phase. + +See: [How to read an often-changing value from useCallback?](https://legacy.reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback) + +### Parameters + +- `fn: (args) => result` - The callback function to be memoized. + +### Return Value + +- `(args) => result` - A memoized event callback function. + +### Features + +- **Memoization**: Optimizes performance by memoizing the callback function to avoid unnecessary re-renders. +- **Prevents Invocation During Render**: Ensures the callback isn't called during rendering, preventing potential issues. +- **Error Handling**: Throws an error if the callback is mistakenly invoked during rendering. +- **Strict Mode Compatibility**: Works seamlessly with React's strict mode for better debugging and reliability. + +### Notes + +Avoid using `useEventCallback` for callback functions that depend on frequently changing state or props. diff --git a/packages/usehooks-ts/src/useEventCallback/useEventCallback.test.tsx b/packages/usehooks-ts/src/useEventCallback/useEventCallback.test.tsx new file mode 100644 index 00000000..9e339ac2 --- /dev/null +++ b/packages/usehooks-ts/src/useEventCallback/useEventCallback.test.tsx @@ -0,0 +1,25 @@ +import { fireEvent, render, renderHook, screen } from '@testing-library/react' + +import { useEventCallback } from './useEventCallback' + +describe('useEventCallback()', () => { + it('should not call the callback during render', () => { + const fn = vi.fn() + const { result } = renderHook(() => useEventCallback(fn)) + + render() + + expect(fn).not.toHaveBeenCalled() + }) + + it('should call the callback when the event is triggered', () => { + const fn = vi.fn() + const { result } = renderHook(() => useEventCallback(fn)) + + render() + + fireEvent.click(screen.getByText('Click me')) + + expect(fn).toHaveBeenCalled() + }) +}) diff --git a/packages/usehooks-ts/src/useEventCallback/useEventCallback.ts b/packages/usehooks-ts/src/useEventCallback/useEventCallback.ts index 79d88dba..d86dbcff 100644 --- a/packages/usehooks-ts/src/useEventCallback/useEventCallback.ts +++ b/packages/usehooks-ts/src/useEventCallback/useEventCallback.ts @@ -8,6 +8,7 @@ import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect' * @template R - The return type of the event callback. * @param {(...args: Args) => R} fn - The callback function. * @returns {(...args: Args) => R} A memoized event callback function. + * @see [Documentation](https://usehooks-ts.com/react-hook/use-event-callback) * @example * const handleClick = useEventCallback((event) => { * // Handle the event here diff --git a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx index 9bd12b75..8de58dd7 100644 --- a/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx +++ b/packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx @@ -1,6 +1,5 @@ import { useLocalStorage } from './useLocalStorage' -// Usage export default function Component() { const [value, setValue] = useLocalStorage('test-key', 0)