DEV Community

Cover image for Common React Design patterns: Custom Hooks
Reza Bozorgi
Reza Bozorgi

Posted on

Common React Design patterns: Custom Hooks

I started a series called "Common React Design Patterns" in which I want to practice some of the major design patterns used in React with each other. So we can be confident enough to apply it in our day-to-day development.

Knowing these patterns is helpful because it can save our time as developers, and it would present the application as a high-performance and delightful experience for our customers.

Custom Hooks

One of the basic design patterns that we use daily is "Custom Hooks." It is vastly used as a preferable way to modularize and apply the DRY principle in our application. We can share complex behavior between multiple components by using a custom hook.

Sample

useDebounce Hook

Tip : Debounce delays invoking a function until after wait milliseconds have elapsed since the last time the debounced function was invoked.

import { useEffect, useState } from 'react'

function useDebounce<T>(value: T, delay?: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value)

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay || 500)

    return () => {
      clearTimeout(timer)
    }
  }, [value, delay])

  return debouncedValue
}

export default useDebounce
Enter fullscreen mode Exit fullscreen mode

By using return function of useEffect after changing value or delay, React clear the timer identifier and function inside setTimeout not going to run. So it debounces. 👌

Usage

import React, { ChangeEvent, useEffect, useState } from 'react'

import { useDebounce } from 'usehooks-ts'

export default function Component() {
  const [value, setValue] = useState<string>('')
  const debouncedValue = useDebounce<string>(value, 500)

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value)
  }

  // Fetch API (optional)
  useEffect(() => {
    // Do fetch here...
    // Triggers when "debouncedValue" changes
  }, [debouncedValue])

  return (
    <div>
      <p>Value real-time: {value}</p>
      <p>Debounced value: {debouncedValue}</p>

      <input type="text" value={value} onChange={handleChange} />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Credit: useHooks-ts *

Libraries

You do not have to build common scenarios from scratch. There are fantastic packages out there you can quickly learn and use. Here I listed some reliable players out of sort.

react-use * ⭐️ 29.6k / 🔽 958k
ahooks * ⭐️ 9.1k / 🔽 74k
awesome-react-hooks * ⭐️ 8.1k / 🔽 74k
usehooks-ts * ⭐️ 1.6k / 🔽 44k
react-recipes * ⭐️ 850 / 🔽 1.2k
react-hanger * ⭐️ 1.8k / 🔽 3.3k

Refrences

React offcial doc *

Top comments (0)