Quasar Nexus

5 Utility Hooks Every React Developer Needs (But Probably Doesn't Know About)

Discover 5 essential React utility hooks that every developer should know: usePrevious, useDebounce, useToggle, useLocalStorage, and useClickOutside. Complete with practical code examples and real-world use cases.


5 Utility Hooks Every React Developer Needs (But Probably Doesn't Know About)

React's custom hooks are powerful, but beyond the usual useState and useEffect, there's a world of utility hooks that can dramatically simplify your components. Here are 5 game-changing utility hooks every developer should know.

1. usePrevious - Access Previous Values

Ever needed to compare current state with its previous value? usePrevious has you covered.

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

// Usage
function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);
  
  return (
    <div>
      <p>Current: {count}, Previous: {prevCount}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

2. useDebounce - Delay Expensive Operations

Perfect for search inputs or API calls that shouldn't fire on every keystroke.

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);
  
  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    
    return () => clearTimeout(handler);
  }, [value, delay]);
  
  return debouncedValue;
}

// Usage
function SearchBox() {
  const [searchTerm, setSearchTerm] = useState('');
  const debouncedSearchTerm = useDebounce(searchTerm, 300);
  
  useEffect(() => {
    if (debouncedSearchTerm) {
      // Make API call here
      console.log('Searching for:', debouncedSearchTerm);
    }
  }, [debouncedSearchTerm]);
  
  return <input onChange={(e) => setSearchTerm(e.target.value)} />;
}

3. useToggle - Simple Boolean State

Clean up your boolean state management with this elegant hook.

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue(v => !v), []);
  return [value, toggle];
}

// Usage
function Modal() {
  const [isOpen, toggleModal] = useToggle(false);
  
  return (
    <>
      <button onClick={toggleModal}>Open Modal</button>
      {isOpen && <div className="modal">Modal Content</div>}
    </>
  );
}

4. useLocalStorage - Persist State

Automatically sync your state with localStorage for persistence across sessions.

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      return initialValue;
    }
  });
  
  const setValue = (value) => {
    try {
      setStoredValue(value);
      window.localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.log(error);
    }
  };
  
  return [storedValue, setValue];
}

// Usage
function Settings() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');
  return <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
    Current theme: {theme}
  </button>;
}

5. useClickOutside - Handle Outside Clicks

Perfect for closing modals, dropdowns, or any element when clicking outside.

function useClickOutside(ref, callback) {
  useEffect(() => {
    function handleClickOutside(event) {
      if (ref.current && !ref.current.contains(event.target)) {
        callback();
      }
    }
    
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [ref, callback]);
}

// Usage
function Dropdown() {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef(null);
  
  useClickOutside(dropdownRef, () => setIsOpen(false));
  
  return (
    <div ref={dropdownRef}>
      <button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
      {isOpen && <div className="dropdown">Dropdown content</div>}
    </div>
  );
}

Conclusion

These utility hooks solve common problems elegantly and keep your components clean. Start incorporating them into your projects, and you'll wonder how you ever lived without them. Happy coding!


More Articles by Quasar Nexus