All About React Hooks

Ravi Sharma
JavaScript in Plain English
14 min readFeb 21, 2023

--

🙏🏻 Namaste, In this article, I will cover all the essential things about react hooks, so if you preparing for react interview then this article is going to be really helpful to you.

What is React Hook?

“React hooks are functions that allow you to use state and other React features without writing a class component. They provide a simple and efficient way to manage state and handle side effects in your functional components.”

Let's see the list of the most useful react hooks used in major react projects and then we will cover all of them one by one with examples.

  1. useContextSelector: This hook allows you to select specific pieces of data from a React context, rather than subscribing to the entire context object. It was introduced in React 18.
  2. useDeferredValue: This hook allows you to delay updates to a value until after a certain amount of time has passed, which can improve performance. It was introduced in React 18.
  3. useTransition: This hook allows you to coordinate transitions between different parts of your React component tree. It was introduced in React 18.
  4. useEvent: This hook allows you to add and remove event listeners in your React component. It was introduced in React 17.
  5. useContextBridge: This hook allows you to pass data from one context to another, which can be useful for avoiding prop drilling. It was introduced in React 17.
  6. useLayoutEffect: This hook is similar to useEffect, but it runs synchronously after all DOM mutations. It was introduced in React 16.8.
  7. useDebugValue: This hook allows you to display custom labels for your custom hooks in the React DevTools. It was introduced in React 16.8.
  8. useImperativeHandle: This hook allows you to expose specific functions or methods from a child component to its parent component. It was introduced in React 16.8.
  9. useState: This hook is used to manage the state in functional components.
  10. useEffect: This hook is used to handle side effects in functional components, such as fetching data from an API or updating the document title.

These are just a few of the newer React Hooks that are available. There are many more hooks available in the React ecosystem, and more are being added all the time.

What is Custom Hook?

Custom React hooks are functions that allow you to encapsulate and reuse logic in your React applications. They are functions that can use one or more built-in hooks to provide some functionality, and can be used across multiple components in your application.

Custom hooks can be used to abstract away complex logic or functionality that would otherwise clutter up your components. They can also be used to share common functionality between different components, improving code reuse and maintainability.

Let’s see the example of a custom hook that tracks the status of an API request:

react custom hook example

In this example, we define a custom hook called useApi that takes an API endpoint as a parameter. Inside the hook, we use the useState and useEffect hooks to manage the state of the API request. When the component that uses this hook mounts, it triggers a fetch request to the specified endpoint. The response is then stored in the data state variable, and any errors are stored in the error state variable. Finally, the isLoading state variable is set to false to indicate that the request is complete.

This custom hook can be used in any component that needs to fetch data from an API, making it a reusable and maintainable solution for handling API requests in your application.

List of React Hook with explanation:

1.useState Hook: useState is a built-in React hook that allows you to manage state in your functional components. It takes an initial value as its argument, and returns an array containing the current state value and a function to update that value.

In this example, we define a Counter component that uses useState to manage the state of a count variable, which is initialized to 0. We also define an increment function that calls the setCount function with the updated value of count.

When the increment button is clicked, the count variable is updated and the component re-renders with the new value. The updated value is displayed in the p element, and the cycle can continue indefinitely.

2.useEffect Hook: useEffect is a built-in React hook that allows you to perform side effects in your functional components. It takes a function as its argument, which will be called after every render cycle.

In this example, we define a Counter component that uses useState to manage the state of a count variable, which is initialized to 0. We also define an increment function that calls the setCount function with the updated value of count.

We use useEffect to set the document title to the current value of count. The effect function will be called after every render cycle, so the document title will be updated whenever the value of count changes.

Here’s a table that maps common class component lifecycle methods to their useEffect equivalent:

a) With an Empty array It works as componentDidMount and Side-effect runs once after the initial rendering.

b) With dependency array it works as componentDidUpdate and side-effect runs once after initial rendering And after every rendering only if dependency value changes.

c) With the return statement (Side-effect clean-up function) it works as componentWillUnmount and Side-effect runs when the component is unmounted. (after unmounting the component, useEffect() invokes the cleanup function from the latest side-effect)

d) Without dependency array and With State update statement inside it. It works as an Infinite loop.

3.useContext Hook: useContext is a hook in React that provides a way to pass data through the component tree without having to pass props down manually at every level.

Here’s an example of how you can use useContext to share data between components:

In this example, we define a MyContext object using the React.createContext function. We also define a MyProvider component that provides the context, and a MyConsumer component that uses the context.

The MyProvider component wraps its children in a MyContext.Provider component, and passes a value to the provider using the value prop.

The MyConsumer component uses the useContext hook to access the value of the context. The hook takes the context object as its argument and returns the current value of the context.

Finally, we render the MyProvider component and the MyConsumer component inside it, causing the consumer to display the value of the shared data.

This way, any component can use the useContext hook to access the value of the shared data without needing to pass it down through props. This can make your code more readable and easier to maintain.

4.useReducer Hook: useReducer is a hook in React that provides a way to manage complex state logic in a more organized way. It is similar to the useState hook, but instead of just updating the state, it allows you to specify how the state should change based on the previous state and an action that is dispatched.

Here’s an example of how you can use useReducer to manage state in a simple counter application:

In this example, we define a counterReducer function that takes the current state and an action object, and returns the new state based on the type of the action.

We also define a Counter component that uses the useReducer hook to manage the state of the counter. The hook takes the reducer function as its first argument, and the initial state as its second argument.

The Counter component defines two functions, handleIncrement and handleDecrement, that dispatch actions to the reducer by calling the dispatch function with an object that includes the type of the action.

Finally, we render the Counter component, which displays the current count and provides buttons to increment and decrement the count.

5.useRef Hook: useRef is a hook in React that provides a way to access and store a mutable value that persists across renders. It is often used to access a DOM element or to store any other value that needs to persist between renders.

Here’s an example of how you can use useRef to access a DOM element:

In this example, we define an InputWithFocusButton component that uses the useRef hook to create a reference to the input element. The hook returns an object with a current property, which is initially set to null.

We define a handleClick function that uses the focus method of the input element to give it focus when the button is clicked.

Finally, we render the InputWithFocusButton component, which displays an input element and a button. When the button is clicked, it calls the handleClick function, which uses the current property of the inputRef object to access the input element and give it focus.

This way, you can use the useRef hook to store a reference to a DOM element or any other value that needs to persist between renders, making it easier to interact with the value in your code.

6.useCallback Hook: useCallback is a hook in React that is used to optimize the performance of a component by memoizing a function so that it is only created once, and returned from cache for subsequent renders. This is particularly useful when a component depends on a function that is expensive to create, or when you want to avoid unnecessary re-renders.

Here’s an example of how you can use useCallback to memoize a function:

In this example, we define a MemoizedList component that takes an array of items and a onSelect function as props. The component uses useState to keep track of the currently selected itemId, and useCallback to memoize the handleSelect function.

The handleSelect function is memoized by wrapping it with useCallback, and passing the onSelect function as a dependency. This ensures that the handleSelect function is only created once, and returned from cache for subsequent renders, as long as the onSelect function does not change.

Finally, we render the MemoizedList component, which displays a list of items, and calls the handleSelect function when an item is clicked. The handleSelect function updates the selectedItemId state and calls the onSelect function with the itemId.

This way, you can optimize the performance of your components by memoizing expensive functions with useCallback, and avoid unnecessary re-renders.

7.useDeferredValue Hook: useDeferredValue is a new hook introduced in React 18 that allows you to defer the rendering of a component until the value of a prop is stable. This can be useful when you want to improve the perceived performance of your app by showing a fallback UI while the main UI is being loaded or processed.

Here’s an example of how you can use useDeferredValue to defer the rendering of a component:

In this example, we define a MyComponent that takes a data prop. We use the useDeferredValue hook to create a new deferredData value that will be deferred by 2 seconds (timeoutMs: 2000) before it is considered stable. We also define a isLoading state that is used to show a loading message while the deferred data is being processed.

Finally, we render the component with a fallback UI that shows a loading message while the deferred data is being processed. Once the deferred data is stable, the useEffect hook runs and updates the isLoading state, which causes the main UI to be rendered with the deferred data.

By deferring the rendering of the component until the value of the deferredData is stable, we can improve the perceived performance of the app by showing a fallback UI while the main UI is being loaded or processed. This can make the app feel more responsive and improve the user experience.

8.useDebugValue Hook: The useDebugValue hook is a utility hook that can be used to display additional information about a value in React DevTools. It is not related to the functional behavior of your component and is only useful for debugging purposes.

Here’s an example of how you can use useDebugValue:

In this example, we define a custom hook called useCustomHook that takes a value argument and uses the useDebugValue hook to display a message in React DevTools. The message indicates whether the value is greater than 10 or less than or equal to 10.

We then use the useCustomHook in MyComponent and pass it a value of 15. The hook will display the message "Value is greater than 10" in React DevTools because 15 is greater than 10.

The useDebugValue hook can be useful for providing additional information about the value of a prop or state in React DevTools. This can help you debug your app and understand the behavior of your components.

9.useContextBridge Hook: The useContextBridge hook is a new hook introduced in React 18 that allows you to share a context between a parent and child component even if they don't have a direct parent-child relationship. This can be useful when you want to share a context between two components that are not directly connected in the component tree.

Here’s an example of how you can use useContextBridge to share a context between two components:

In this example, we define a MyContext that provides a value of "World". We then define a Parent component that has a state of "Hello" and creates a bridge with useContextBridge for the MyContext. We pass this bridge down to a Child component.

In the Child component, we use useContext to get the value from the bridge. This allows us to share the context between the Parent and Child components even though they don't have a direct parent-child relationship.

Finally, we render the Parent component inside the MyContext.Provider.

By using the useContextBridge hook, we can share a context between two components that are not directly connected in the component tree. This can make it easier to share data between components and simplify the architecture of our React application.

10.useImperativeHandle Hook: The useImperativeHandle hook is a utility hook that can be used to customize the instance value that is exposed to parent components when using ref in React. It allows you to define functions or properties that can be accessed from the parent component using the ref.

Here’s an example of how you can use useImperativeHandle:

In this example, we define a Child component that uses useImperativeHandle to expose a focusInput function to the parent component. We create a ref using useRef to access the child component.

In the Parent component, we render the Child component and pass the ref to it. We then define a button that calls the focusInput function on the child component when clicked.

By using the useImperativeHandle hook, we can define functions or properties that are exposed to parent components using ref in React. This allows us to customize the behavior of the child component and make it more flexible and reusable.

How To use React Hook - Some rules to note down:

Here are some rules to keep in mind when using React Hooks:

  1. Hooks can only be used at the top level of a functional component or another hook. You cannot use them inside loops, conditions, or nested functions.
  2. Hooks must be called in the same order on every render of a component. This ensures that React can properly associate stateful values with their respective hooks.
  3. You should only call hooks from within function components or other custom hooks. Do not call hooks from regular JavaScript functions.
  4. Do not conditionally call hooks. Hooks must be called on every render of a component, so you should not put them inside if statements or other conditional blocks.
  5. Do not use hooks inside classes. Hooks are only meant to be used in function components or custom hooks.

By following these rules, you can ensure that your use of React Hooks is consistent and avoids common issues that can lead to bugs in your application.

Example of Custom Hooks:

1. Let’s see the example of a custom react hook to implement debounce functionality in react

This hook takes in two parameters: value, which is the value that you want to debounce, and delay, which is the number of milliseconds to wait before updating the debounced value.

Inside the hook, we use the useState hook to keep track of the current debouncedValue, and we initialize it to the initial value that was passed in.

We then use the useEffect hook to set up a timer that will update the debouncedValue after the specified delay. We pass in the value and delay as dependencies for the effect so that it only runs when they change.

Finally, we return the debouncedValue from the hook, which will be updated only after the specified delay has elapsed without any changes to the value.

You can use this hook in your components to debounce any value, such as user input or API requests, by passing in the value you want to debounce and the delay time, like this:

2. Let’s see the example of a custom react hook for getting network-status.

Here’s an example of a custom React hook that uses the navigator.onLine API to check the network status of the user's device:

This hook returns a boolean value representing the current network status of the user’s device. It uses the useState hook to keep track of this value and initializes it with the value of navigator.onLine at the time of rendering.

The hook also defines an updateStatus function that updates the isOnline state to the current value of navigator.onLine. We then use the useEffect hook to add event listeners for the online and offline events and call the updateStatus function to update the state accordingly.

The useEffect hook also returns a cleanup function that removes the event listeners when the component unmounts, to avoid memory leaks.

Here’s an example of how you could use this hook in a component:

In this example, we use the useNetworkStatus hook to check the network status of the user's device and display a message accordingly. We use the isOnline value returned by the hook to conditionally render either an "online" or "offline" message.

🙏🏻Thanks for reading 🧑‍💻

If you enjoyed reading this article, please follow me, if you have any questions or comments, I would love to hear from you — feel free to leave a comment or send an email.

Thank you for taking the time to read this article, and I look forward to sharing more content with you in the future.

More content at PlainEnglish.io.

Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.

Interested in scaling your software startup? Check out Circuit.

--

--