If you’re new to React, or even just JavaScript in general, the concept of “hooks” can be a little confusing at first. But once you understand what they are and how they work, they can be a powerful tool for building smarter and more reusable components.

In this article, we’ll cover what React hooks are, how they work, and some of the most popular hooks available. By the end, you should have a good understanding of how to use React hooks in your own projects.

What are React Hooks?

React hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes.

There are two main types of hooks: built-in hooks like useState, and custom hooks that let you create your own hook functions. We’ll cover both types in this article.

The useState hook

The useState hook is the most basic hook available in React. It lets you add local state to a function component — which is something that was not possible before hooks were introduced.

To use the useState hook, you call the function with an initial value:

    const [count, setCount] = useState(0);  // initial value is 0

This creates a count variable in our component’s state, with an initial value of 0. We can update the value of count by calling setCount with a new value:

    setCount(1);  // sets count to 1

    setCount(prevCount => prevCount + 1);  // increments count by 1 (useful for async operations)

Whenever we call setCount, our component will re-render with the new value of count.

The useEffect hook

The useEffect hook lets you perform side effects in function components. Side effects are operations that don’t directly affect the component’s state, but might have an impact elsewhere — like making a network request, or setting up a subscription.

In class-based components, we would typically put side effects in componentDidMount and componentDidUpdate lifecycle methods. With hooks, we can call useEffect inside our components to run these side effects:

    useEffect(() => {
      // runs on initial render and on each update

      // cleanup function runs when the component unmounts (or on each update)

      return () => {};  // optional cleanup function
    });

The useContext hook

The useContext hook lets you access React context from inside a function component. Context is a way to pass data down the component tree without having to prop-drill it all the way down.

To create a context, we first need to create a context object with React.createContext:

    const MyContext = React.createContext();

Then, we can wrap our root component in this context object:

    <MyContext.Provider value={/* some data */}>...</MyContext.Provider>   // root component gets wrapped in provider tag

Now any child of the root component can access the data in MyContext by using the useContext hook:

    const myData = useContext(MyContext);  // myData will be equal to whatever is passed as the value prop in <MyContext.Provider>

Other React hooks

There are several other React hooks available, like useReducer (for managing complex state in a function component), useCallback (for memoizing callback functions), and useRef (for creating mutable variables that don’t trigger a re-render when they’re updated).

For a full list of hooks, check out the React docs.

Wrapping Up

React hooks are a powerful new feature that lets you add state and other React features to function components. In this article, we covered the most popular hooks — useState, useEffect, and useContext. With these hooks, you can handle just about anything you could do with a class component.