DEV Community

Maria M.
Maria M.

Posted on

4 1 1 2 1

A Complete Overview of Built-in React Hooks 🚀

React Hooks let you use React features from your functional components. Here is a guide to the most important built-in hooks and how to use them with examples.

State Hooks 🧠

useState

useState allows you to add state to a functional component.

import { useState } from "react";

function 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

useReducer

useReducer is useful for managing complex state with update logic inside a reducer function.

import { useReducer } from "react";

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function 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

Context Hooks 🌐

useContext

useContext allows a component to subscribe to a context without passing props.

import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return (
    <button style={{ background: theme.background, color: theme.color }}>
      Themed Button
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

Ref Hooks 🪝

useRef

useRef lets you access a DOM element directly.

import { useRef } from "react";

function TextInput() {
  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

Effect Hooks 🌟

useEffect

useEffect is used for side effects in components, like fetching data or subscribing to events.

import { useEffect, useState } from "react";

function DataFetcher({ url }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(url);
      const result = await response.json();
      setData(result);
    };

    fetchData();
  }, [url]);

  return (
    <div>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Performance Hooks ⚡

useMemo

useMemo memoizes an expensive calculation and reuses it.

import { useMemo } from "react";

function TodoList({ todos, tab }) {
  const visibleTodos = useMemo(() => {
    return todos.filter(todo => todo.tab === tab);
  }, [todos, tab]);

  return (
    <ul>
      {visibleTodos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

useCallback

useCallback memoizes a function to avoid recreating it on every render.

import { useCallback } from "react";

function ParentComponent() {
  const handleClick = useCallback(() => {
    console.log("Button clicked");
  }, []);

  return <ChildComponent onClick={handleClick} />;
}

function ChildComponent({ onClick }) {
  return <button onClick={onClick}>Click me</button>;
}
Enter fullscreen mode Exit fullscreen mode

Transition Hooks 🌈

useTransition

useTransition marks a state transition as non-blocking.

import { useState, useTransition } from "react";

function List({ items }) {
  const [isPending, startTransition] = useTransition();
  const [query, setQuery] = useState('');

  const handleChange = (e) => {
    startTransition(() => {
      setQuery(e.target.value);
    });
  };

  const filteredItems = items.filter(item => item.includes(query));

  return (
    <div>
      <input type="text" value={query} onChange={handleChange} />
      {isPending && <p>Loading...</p>}
      <ul>
        {filteredItems.map(item => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

useDeferredValue

useDeferredValue defers updating a non-critical part of the UI.

import { useState, useDeferredValue } from "react";

function SearchResults({ query, results }) {
  const deferredQuery = useDeferredValue(query);

  const filteredResults = results.filter(item => item.includes(deferredQuery));

  return (
    <ul>
      {filteredResults.map(result => (
        <li key={result}>{result}</li>
      ))}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Conclusion 🎉

React Hooks are powerful tools that allow you to manage state, context, effects, and performance of your functional components efficiently. Using these hooks correctly can significantly improve the quality and maintainability of your code. Happy coding! 🚀

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay