DEV Community

Maria M.
Maria M.

Posted on

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! 🚀

Top comments (0)