All About React Hooks
🙏🏻 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.
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.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.useTransition
: This hook allows you to coordinate transitions between different parts of your React component tree. It was introduced in React 18.useEvent
: This hook allows you to add and remove event listeners in your React component. It was introduced in React 17.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.useLayoutEffect
: This hook is similar touseEffect
, but it runs synchronously after all DOM mutations. It was introduced in React 16.8.useDebugValue
: This hook allows you to display custom labels for your custom hooks in the React DevTools. It was introduced in React 16.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.useState
: This hook is used to manage the state in functional components.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:
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:
- 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.
- 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.
- You should only call hooks from within function components or other custom hooks. Do not call hooks from regular JavaScript functions.
- 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.
- 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.