DEV Community

Cover image for Level Up Your React Skills: Understanding and Using Hooks
Md Nazmus Sakib
Md Nazmus Sakib

Posted on

Level Up Your React Skills: Understanding and Using Hooks

React hooks are special functions that allow you to use React features, such as state and lifecycle methods, in functional components. They were introduced in React 16.8 to simplify the component model and make it easier to share stateful logic across components.

Key Features of React Hooks:

State Management: Hooks like useState allow you to add and manage state in functional components without needing to convert them to class components.

Side Effects: The useEffect hook lets you perform side effects, such as data fetching, subscriptions, or manually changing the DOM, similar to lifecycle methods in class components.

Reusability: Custom hooks allow you to encapsulate and reuse stateful logic across different components.

Cleaner Code: Hooks help to keep components o

Built-in Hooks

1 useState

  • Description: Allows you to add state to functional components.
  • Example:
   import React, { useState } from 'react';

   const Counter = () => {
     const [count, setCount] = useState(0);
     return (
       <div>
         <p>Count: {count}</p>
         <button onClick={() => setCount(count + 1)}>Increment</button>
       </div>
     );
   };
Enter fullscreen mode Exit fullscreen mode

2 useEffect

  • Description: Manages side effects, such as data fetching or subscriptions, in functional components.
  • Example:
   import React, { useEffect, useState } from 'react';

   const DataFetcher = () => {
     const [data, setData] = useState(null);
     useEffect(() => {
       fetch('https://api.example.com/data')
         .then(response => response.json())
         .then(setData);
     }, []);
     return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
   };
Enter fullscreen mode Exit fullscreen mode

3 useContext

  • Description: Provides access to context values without needing a consumer.
  • Example:
   import React, { useContext } from 'react';

   const ThemeContext = React.createContext('light');

   const ThemedComponent = () => {
     const theme = useContext(ThemeContext);
     return <div className={`theme-${theme}`}>Current theme: {theme}</div>;
   };
Enter fullscreen mode Exit fullscreen mode

4 useReducer

  • Description: Manages complex state logic in components, similar to Redux.
  • Example:
   import React, { useReducer } from 'react';

   const initialState = { count: 0 };
   const reducer = (state, action) => {
     switch (action.type) {
       case 'increment':
         return { count: state.count + 1 };
       case 'decrement':
         return { count: state.count - 1 };
       default:
         return state;
     }
   };

   const Counter = () => {
     const [state, dispatch] = useReducer(reducer, initialState);
     return (
       <div>
         <p>Count: {state.count}</p>
         <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
         <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
       </div>
     );
   };

Enter fullscreen mode Exit fullscreen mode

5 useMemo

  • Description: Memoizes a computed value to optimize performance, avoiding unnecessary recalculations.
  • Example:
   import React, { useMemo, useState } from 'react';

   const ExpensiveComputation = ({ number }) => {
     const compute = (num) => {
       return num * 1000; // Simulate an expensive computation
     };
     const result = useMemo(() => compute(number), [number]);
     return <div>Computed Result: {result}</div>;
   };
Enter fullscreen mode Exit fullscreen mode

6 useCallback

  • Description: Returns a memoized version of a callback function that only changes if one of the dependencies has changed.
  • Example:
   import React, { useCallback, useState } from 'react';

   const Button = React.memo(({ onClick, children }) => {
     console.log('Button rendered');
     return <button onClick={onClick}>{children}</button>;
   });

   const App = () => {
     const [count, setCount] = useState(0);
     const increment = useCallback(() => setCount(c => c + 1), []);
     return (
       <div>
         <p>Count: {count}</p>
         <Button onClick={increment}>Increment</Button>
       </div>
     );
   };
Enter fullscreen mode Exit fullscreen mode

7 useRef

  • Description: Returns a mutable ref object that persists for the full lifetime of the component, useful for accessing DOM elements directly.
  • Example:
   import React, { useRef } from 'react';

   const FocusInput = () => {
     const inputRef = useRef(null);
     const focusInput = () => {
       inputRef.current.focus();
     };
     return (
       <div>
         <input ref={inputRef} type="text" />
         <button onClick={focusInput}>Focus Input</button>
       </div>
     );
   };
Enter fullscreen mode Exit fullscreen mode

8 useLayoutEffect

  • Description: Similar to useEffect, but runs synchronously after all DOM mutations, allowing for measurement of the DOM layout.
  • Example:
   import React, { useLayoutEffect, useRef } from 'react';

   const LayoutEffectExample = () => {
     const divRef = useRef();
     useLayoutEffect(() => {
       console.log('Height:', divRef.current.clientHeight);
     }, []);
     return <div ref={divRef}>This is a div</div>;
   };
Enter fullscreen mode Exit fullscreen mode

9 useImperativeHandle

  • Description: Customizes the instance value that is exposed when using ref in parent components.
  • Example:
   import React, { useImperativeHandle, forwardRef, useRef } from 'react';

   const CustomInput = forwardRef((props, ref) => {
     const inputRef = useRef();
     useImperativeHandle(ref, () => ({
       focus: () => {
         inputRef.current.focus();
       }
     }));
     return <input ref={inputRef} type="text" />;
   });

   const Parent = () => {
     const ref = useRef();
     return (
       <div>
         <CustomInput ref={ref} />
         <button onClick={() => ref.current.focus()}>Focus Input</button>
       </div>
     );
   };
Enter fullscreen mode Exit fullscreen mode

10 useDebugValue
- Description: Displays a label for custom hooks in React DevTools for easier debugging.
- Example:

import { useDebugValue } from 'react';

    const useCustomHook = (value) => {
      useDebugValue(value ? 'Value is true' : 'Value is false');
      return value;
    };

    const DebugExample = () => {
      const isTrue = useCustomHook(true);
      return <div>Check the React DevTools</div>;
    };

Enter fullscreen mode Exit fullscreen mode

Custom Hooks

11 useFetch
- Description: A custom hook for fetching data from an API.
- Example:

 import { useState, useEffect } from 'react';

    const useFetch = (url) => {
      const [data, setData] = useState(null);
      const [loading, setLoading] = useState(true);

      useEffect(() => {
        const fetchData = async () => {
          const response = await fetch(url);
          const result = await response.json();
          setData(result);
          setLoading(false);
        };
        fetchData();
      }, [url]);

      return { data, loading };
    };
Enter fullscreen mode Exit fullscreen mode

12 useLocalStorage
- Description: Syncs state with local storage to persist data across sessions.
- Example:

import { useState, useEffect } from 'react';

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

      useEffect(() => {
        try {
          window.localStorage.setItem(key, JSON.stringify(storedValue));
        } catch (error) {
          console.error(error);
        }
      }, [key, storedValue]);

      return [storedValue, setStoredValue];
    };

Enter fullscreen mode Exit fullscreen mode

13 usePrevious
- Description: Returns the previous value of a state or prop.
- Example:

import { useRef, useEffect } from 'react';

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

Enter fullscreen mode Exit fullscreen mode

14 useDebounce
- Description: Debounces a value or function call, delaying execution until after a specified delay.
- Example:

 import { useState, useEffect } from 'react';

    const useDebounce = (value, delay) => {
      const [debouncedValue, setDebouncedValue] = useState(value);

      useEffect(() => {
        const handler = setTimeout(() => {
          setDebouncedValue(value);
        }, delay);

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

      return debouncedValue;
    };
Enter fullscreen mode Exit fullscreen mode

15 useOnClickOutside
- Description: Detects clicks outside a specified element, useful for closing popups or dropdowns.
- Example:

import { useEffect } from 'react';

    const useOnClickOutside = (ref, handler) => {
      useEffect(() =>

 {
        const listener = (event) => {
          if (!ref.current || ref.current.contains(event.target)) {
            return;
          }
          handler(event);
        };
        document.addEventListener('mousedown', listener);
        return () => {
          document.removeEventListener('mousedown', listener);
        };
      }, [ref, handler]);
    };
Enter fullscreen mode Exit fullscreen mode

16 useInterval
- Description: Sets up an interval to run a function repeatedly at specified intervals.
- Example:

 import { useEffect } from 'react';

    const useInterval = (callback, delay) => {
      useEffect(() => {
        const interval = setInterval(callback, delay);
        return () => clearInterval(interval);
      }, [callback, delay]);
    };
Enter fullscreen mode Exit fullscreen mode

17 useTimeout
- Description: Sets up a timeout to execute a function after a specified delay.
- Example:

import { useEffect } from 'react';

    const useTimeout = (callback, delay) => {
      useEffect(() => {
        const timer = setTimeout(callback, delay);
        return () => clearTimeout(timer);
      }, [callback, delay]);
    };

Enter fullscreen mode Exit fullscreen mode

18 useMediaQuery
- Description: Checks if a media query matches, allowing for responsive design logic.
- Example:

  import { useState, useEffect } from 'react';

    const useMediaQuery = (query) => {
      const [matches, setMatches] = useState(window.matchMedia(query).matches);

      useEffect(() => {
        const mediaQueryList = window.matchMedia(query);
        const listener = (event) => setMatches(event.matches);
        mediaQueryList.addEventListener('change', listener);
        return () => mediaQueryList.removeEventListener('change', listener);
      }, [query]);

      return matches;
    };

Enter fullscreen mode Exit fullscreen mode

19 useScrollPosition
- Description: Tracks the current scroll position of the window.
- Example:

import { useState, useEffect } from 'react';

    const useScrollPosition = () => {
      const [scrollPosition, setScrollPosition] = useState(0);

      const handleScroll = () => {
        setScrollPosition(window.scrollY);
      };

      useEffect(() => {
        window.addEventListener('scroll', handleScroll);
        return () => {
          window.removeEventListener('scroll', handleScroll);
        };
      }, []);

      return scrollPosition;
    };

Enter fullscreen mode Exit fullscreen mode

20 useKeyPress
- Description: Detects whether a specific key is pressed.
- Example:


    import { useState, useEffect } from 'react';

    const useKeyPress = (targetKey) => {
      const [keyPressed, setKeyPressed] = useState(false);

      const downHandler = ({ key }) => {
        if (key === targetKey) {
          setKeyPressed(true);
        }
      };

      const upHandler = ({ key }) => {
        if (key === targetKey) {
          setKeyPressed(false);
        }
      };

      useEffect(() => {
        window.addEventListener('keydown', downHandler);
        window.addEventListener('keyup', upHandler);
        return () => {
          window.removeEventListener('keydown', downHandler);
          window.removeEventListener('keyup', upHandler);
        };
      }, []);

      return keyPressed;
    };

Enter fullscreen mode Exit fullscreen mode

Summary

This list now includes descriptions for each hook, providing a clearer understanding of their purposes and use cases. If you need any more details or examples, feel free to ask!

Top comments (0)