React Hooks are a new addition to React that allow you to use state and other React features without writing a class component. JavaScript functions known as “Hooks” allow you to “hook into” React state and lifecycle features from function components. 

What Are React Hooks?

React Hooks are methods that allow you to make use of state and other React capabilities without writing a class component. They “hook into” React state and lifecycle features from function components and simplify state management. Common React Hooks include: useState(), useReducer(), useEffect(), useLayoutEffect(), useCallback() and useMemo()

Hooks have greatly simplified state management and lifecycle handling in functional components, making them a powerful tool in modern React development.

 

React Hooks Overview

React Hooks are useful in a variety of situations, and they offer a more flexible way to manage state and side effects in functional components. Hooks are particularly useful for a number of tasks, including:

  1. Writing reusable stateful logic. Using Hooks, you can take stateful logic out of a component and put it into a different function that you may use in other components. Your code may become easier to maintain and more modular as a result.
  2. Writing performant code. Hooks minimize the amount of code that needs to be rendered again after each interaction, which can assist you in writing code that is more performant.
  3. Writing easy-to-maintain code. Hooks increase the modularity and ease of reasoning in your code, which can help you write code that is easy to maintain.

 

When to Use React Hooks

React Hooks let developers create modular and reusable components, which makes them ideal for single page applications (SPA). React SPAs are web applications that load a single HTML page and dynamically update the content as the user interacts with the application. Some specific ways that Hooks can be used in SPAs, include:

  1. Managing state: You can use React Hooks to handle a component’s state without writing a class component. This facilitates the creation of modular and reusable components.
  2. Handling side effects: Redux or other state management tools don’t need to be utilized for sharing data between components thanks to React Hooks. SPAs may become simpler and easier to maintain as a result.
  3. Sharing data between components: Without writing a class component, React Hooks can be used to manage side effects like changing the document object model (DOM) or retrieving data from an API. As a result, SPAs may become more practical and performant.

 

3 Rules of React Hooks

There are three rules for React Hooks:

  1. Hooks can only be called inside React function components. This means that you can’t call hooks inside of class components or inside of any other type of function.
  2. Hooks can only be called at the top level of a component. This implies that using hooks inside of nested functions, conditional expressions or loops is not recommended. This is because for React to render your component correctly, it needs to know which hooks are invoked in what sequence.
  3. Hooks must be called in the same order on every render. This means that hooks must be called in the same order on every render to ensure React can correctly manage the state and side effects associated with each hook.

 

6 React Hooks With Example Code

React Hooks are methods that let functional components make use of state and other React capabilities. These are a few pre-built React hooks, along with some sample code:

 

1. useState()

You can control the state of functional components by using the useState() hook. It accepts an initial value as input and outputs an array containing the value of the state as it is at that moment as well as a function to update the state.

useState() example code.
useState() example code. | Image: Akshay Kumar

In the example above, the useState() hook is used to initialize a state variable called count. The initial value of count is set to 0. The useState() hook also returns a function called setCount().

The code returns the JSX that contains <div> element that contains two child elements: a <p> element that displays the current count value, and a <button> element that increments the count value when it is clicked. The onClick prop of the <button> element is a callback function that calls the setCount function to increment the count value.

This function can be used to update the state of count.

When the user clicks on the button, the setCount() function is called to increment the value of count. This causes the component to re-render with the updated value of count.

 

2. useReducer()

This hook is utilized to handle state. Compared to the useState hook, the useReducer hook provides a more structured and organized method of managing complex state logic in React.

A reducer function and an initial state value are the two arguments it requires. The reducer function is a pure function that returns the new state after receiving as inputs the action object and the current state.

Usually, the action object is an object that specifies the action that has to be taken on the state. An array holding the current state and a dispatch function is returned by the useReducer hook. The reducer function receives actions from the dispatch function and modifies the state appropriately.

useReducer example code.
useReducer example code. | Image: Akshay Kumar

In the example above, the useReducer() hook is used to initialize a state object with a key called count. The initial value of count is set to 0. The useReducer() hook also returns a function called dispatch(). This function can be used to dispatch actions to the reducer function. 

When the user clicks on the button, the dispatch() function is called to dispatch an action with the type increment. The reducer function then handles the action and returns a new state object with the updated value of count. This causes the component to rerender with the updated state.

The useReducer hook comes in handy when managing more complex state logic, especially when the state can be used for more than one action. With a context API, it may also be utilized to maintain state across many components.

 

3. useEffect()

React’s useEffect hook is a flexible utility that lets you apply side effects to function components. Data fetching, subscriptions, editing the DOM by hand, and timer setup are a few examples of these side effects. A function and an optional array of dependencies are the two arguments required by the useEffect hook.

The function, which is the effect itself, will be used once the component has finished rendering. If given, the dependencies array indicates which values the effect depends on. The effect will be re-executed if any of the dependencies change. 

Additional actions that can be carried out using the useEffect hook include managing subscriptions, directly altering the DOM and establishing timers. It’s an effective tool for managing different jobs that don’t require the rendering of the component.

useEffect hook code example.
useEffect hook code example. | Image: Akshay Kumar

 

4. useLayoutEffect()

useLayoutEffect is a React Hook that functions similarly to useEffect except that it runs synchronously following the completion of all DOM modifications. For tasks like measuring DOM elements, executing animations, or synchronously re-rendering the DOM in response to layout changes, it’s important that the DOM can maintain a consistent state. 

useLayoutEffect is primarily used for DOM-related side effects that ask for instantaneous DOM updates, although useEffect is often favored for the majority of side effects.

useLayouteffect hook example.
useLayouteffect hook example. | Image: Akshay Kumar

 

5. useCallback() 

The useCallback hook is a speed optimization feature that helps to memoize callback methods so they don’t have to be generated on every render. It requires a function as well as an optional dependents array as parameters. The callback you wish to memoize is represented by the function, and the variables the callback depends on are specified by the dependencies array.

useCallback, like useMemo, enhances performance by avoiding pointless re-renders. When a child component receives a callback function, it will render again whenever the parent component does.

useCallback hook example.
useCallback hook example. | Image: Akshay Kumar

 

6. useMemo() 

React’s useMemo hook lets you memoize costly computations to avoid having to do them again on each render. It requires a function as well as an optional dependents array as parameters. 

The calculation you wish to memoize is called a function, and the values the calculation depends on are specified in the dependents array. The calculation will be repeated, and the cached value updated if any of the dependents change. In the absence of that, the cached value will be given back.

The useMemo hook is particularly useful for performance optimization, especially when dealing with expensive calculations that don’t frequently change. It can help improve the performance of your React components by preventing unnecessary work and reducing unnecessary re-renders.

useMemo() hook example code.
useMemo() hook example code. | Image: Akshay Kumar

 

React State Hooks

React state hooks are used to control the state of functional components. Before state hooks, using a class component was the only option available to manage state in functional components.

There are two state hooks:

  1. useState(): You can control the state of functional components by using the useState() hook. It accepts an initial value as input and outputs an array containing the value of the state as it is at that moment as well as a function to update the state.
  2. useReducer(): Using a reducer function, this hook is utilized to handle state. It accepts two parameters: a reducer function and the initial state value. In return, it produces an array containing two elements: the action dispatch function and the current state value.

 

React Context Hooks

React’s context hooks allow data to be passed through the component tree without requiring props to be manually passed down at each level. Data like the theme that is currently being used, the user that is logged in or the locale can be shared between other components with this.

You must first build a context object in order to use context hooks. The createContext() function can be used for this. Provider and Consumer are the two properties of the object returned by the createContext() function.

The context value is supplied to its offspring via the Provider component. The context value from its parent is consumed by the Consumer component.

Context hooks code example.
Context hooks code example. | Image: Akshay Kumar

In the example above, the ThemeProvider component is used to provide the current theme to its descendants. The ThemeConsumer component is used to consume the current theme from its parent. The createContext() function creates a new context object. The context object has two properties: Provider and Consumer. The Provider property is a component that allows you to provide the context value to your child components. The Consumer property is a component that allows you to consume the context value in your child components.

When the user clicks on the button, the ThemeProvider component re-renders with the updated theme. This causes all of the ThemeConsumer components in the tree to re-render with the updated theme.

Context hooks are a powerful way to share data across multiple components in a React application. They can make your code more reusable and maintainable.

The following are some more advantages of utilizing context hooks:

  • They can decrease the need for prop drilling. 
  • They can increase the modularity and reusability of your code.
  • They can facilitate easier code maintenance.

 

Performance Hooks

There are two common React Hooks that can be used to improve performance. These include: useMemo() and useCallback()

 

1. useMemo()

React’s useMemo hook is a performance optimization technique that lets you memoize costly computations to avoid having to do them again on each render. A function and an optional dependents array are its two required arguments. The dependencies array lists the numbers that the calculation depends on, and the function represents the computation you wish to memoize.

To mitigate this, the useMemo hook memoizes the outcomes of costly computations, saving them from having to be done again each time the component renders. Performance can be greatly enhanced by this, particularly for parts that handle complex calculations or data processing.

useMemo hook example code.
useMemo hook example code. | Image: Akshay Kumar

 

2. useCallback() 

Like useMemo, another efficiency-enhancing technique in React is the useCallback hook. By allowing you to memoize callback methods, you can avoid having to recreate them on every render. This can be especially helpful for giving callback functions to child components, as it makes sure that the same reference is sent each time the parent component renders, saving the child components from having to receive a new function each time.

UseCallback’s primary purpose is to stop child components from needlessly re-rendering themselves when callback references change. React generates a new function reference on each render of the parent component when you send a callback function to a child component.

useCallback code example.
useCallback code example. | Image: Akshay Kumar

In the example above, the useCallback() hook is used to memoize the handleClick() function. This means that the handleClick() function will only be recreated if the value of count changes. This can improve performance by avoiding the unnecessary recreation of the handleClick() function.

 

React Effect Hooks

React effect Hooks are used in functional components to execute side effects. Side effects are things like data fetching, subscription setup and DOM updates that happen outside of a component’s render cycle.

The two main effect hooks are:

  • useEffect(): This allows you to apply side effects to function components. 
  • useLayoutEffect(): This hook operates similarly to useEffect except that it runs synchronously following the completion of all DOM modifications.

 

Benefits of React Hooks

Using React Hooks has the following benefits: 

  • They improve the reusability and maintainability of code. You can divide your code into more manageable, targeted functions by using Hooks. This facilitates reading, comprehending, and testing of your code.
  • They cut down on drilling props. Instead of manually passing props down at each level, Hooks let you transfer data down the component tree. This can help you write more succinct code and minimize prop drilling.
  • They facilitate state administration. UseState and useReducer are only two of the many built-in state management capabilities that Hooks offer. The management of state in functional components is made simple by these tools.
  • They improve performance. Hooks can help to improve the performance of your React components by memoizing expensive computations and callback functions.
  • They increase the power of functioning components. You can leverage React capabilities like state and others in functional components by using hooks. Functional components become more potent and adaptable as a result.
  • They improve consistency in the code. In React components, Hooks offer a standardized method for handling state and executing side effects. This can improve the consistency and readability of your code.
  • Compared to class components, they are simpler to learn. Although Hooks are not as old as class components, they are usually simpler to understand and utilize.

 

Best Practices for React Hooks

The following are some criteria for using React Hooks:

  • Hooks should only be used at the component’s top level. As we highlighted earlier, using Hooks inside of nested functions, conditional expressions or loops is not recommended. 
  • Use hooks only in parts that are functional. Hooks are not allowed in class components.
  • Make use of evocative hook names. Your code will become easier to read and maintain as a result.
  • To encapsulate functionality, use hooks. Your code will become more modular and reusable as a result.
  • To increase efficiency, take advantage of the useMemo() and useCallback() hooks. By memoizing costly computations and callback methods, these hooks can lower the amount of re-renders required.
  • To execute side effects, utilize the useEffect() hook. This covers tasks like changing the DOM, creating subscriptions, and retrieving data.
  • For side effects that must be completed before updating the browser layout, use the useLayoutEffect() hook. This is helpful for tasks like determining an element’s size and location on the screen.
A tutorial on the most common React Hooks and how they work. | Video: Fireship

More on ReactWhy Is React a Library and Next.JS a Framework?

 

React Custom Hooks

React custom hooks are functions that encapsulate common functionality by using other hooks. They can be used to build reusable components, abstract away complex state management logic, and isolate and test individual components.

All you have to do is write a function that begins with the word “use” to build a custom hook. For example:

React custom hooks example code.
React custom hooks example code. | Image: Akshay Kumar

This custom hook encapsulates the logic for fetching data from a URL. It takes the URL as an argument and returns an object with the following properties:

  • data: The fetched data, or null if the data has not been fetched yet or if there was an error.
  • isLoading: A boolean indicating whether the data is currently being fetched.
  • error: The error object, or null if there was no error.

To use the custom hook, you would simply import it into your component and call it:

React custom hooks example continued.
React custom hooks code. | Image: Akshay Kumar

This part will retrieve the information from the API and present it as a list. A loading spinner will appear on the component if the data is still being fetched. The component will display an error message if there is a problem.

Any common functionality can be encapsulated using custom hooks. You could, for instance, make unique hooks for the following:

  • Managing in a complex approach. 
  • Checking the input on a form.
  • Working with animations.
  • Interacting with third-party APIs.
  • Testing individual components.

Using custom hooks is a great method to increase the reusability, maintainability and testability of your React code.

 

Frequently Asked Questions

What are React Hooks?

React hooks are functions that let you use state and other React features in functional components. They are a new feature in React 16.8.

Why use React Hooks?

React hooks offer a number of benefits, including making code more reusable and maintainable, reducing prop drilling, and making state management easier.

Expert Contributors

Built In’s expert contributor network publishes thoughtful, solutions-oriented stories written by innovative tech professionals. It is the tech industry’s definitive destination for sharing compelling, first-person accounts of problem-solving on the road to innovation.

Learn More

Great Companies Need Great People. That's Where We Come In.

Recruit With Us