A recent addition to the React library, Hooks, has fundamentally altered how developers create React components. Without having to create a class component, hooks enable functional components to access other React features and have a state.
Before Hooks, class components were the only option to add a state to a React component. However, as the complexity of the React component increased, class components became lengthy and challenging to comprehend. Developers can manage state and other logic in a functional component using hooks, which makes their code shorter and simpler to comprehend.
Hooks quickly became an integral part of the React community, offering intuitive and efficient ways to manage the logic of components and making the code easier to understand and execute. It has revolutionized the way React components are written.
This article will cover both the basic and advanced concepts of hooks so you can understand how to use them to create robust, scalable, and flexible applications. By the end of this article, you will have a good understanding of hooks and be able to use them in your own projects.
What are Hooks?
Functional components can now handle state and execute side effects that were formerly only available in class components, thanks to React Hooks. Developers can build a cleaner, more reusable code with hooks, which makes the codebase simpler to comprehend and maintain.
Hooks in React enable you to efficiently bring state and other functionality to your functional components by providing them the functionality of the class components.
There are two types of hooks; state hooks and effect hooks. The table below presents a brief comparison between the two.
State Hooks | Effect Hooks |
State hooks enable you to efficiently add and update the state to the functional component. | Effect hooks enable you to execute your functional component’s side effects. |
They are used to track the state value in the functional components. | They are used for side effects, which include getting the data with the help of an API, modifying the DOM, and establishing the timer. |
The useState returns the tuple which contains the current state value and state updater function that enables the modification of state value. | The useEffect returns a function used to reverse the modifications made due to the side effect. |
With the help of hooks, the application and the code become efficient, reusable, and easier to understand. In addition, components can share hooks, making it simpler to share their state and further functionality throughout the applications.
Why Should You Use Hooks in React?
React Hooks transform your functional components to give you unparalleled flexibility, streamlined state management, and efficient code. Let’s take a look at how these hooks can help you in the application development process.
- Hooks help make your code easier to understand and increase readability by effectively incorporating state and other functionality into the functional components. As a result, it allows you to create easily readable and modified code.
- Hooks improve the reusability of the code by sharing them among the components, making it simpler to share their state and further functionality efficiently among their applications. It helps in reducing the code and make it reusable.
- Hooks improve the application’s performance by optimizing it with the help of useMemo hooks which help in memorizing the calculations. It helps in enhancing the performance of the application.
- Hooks improve the developer’s experience by simplifying the functionalities into the components by minimizing the number of class components. It increases productivity and efficiency and gives more satisfying results.
We will now look at an example to familiarize you with the usage of hooks. This example demonstrates the useCallback hook.
import React, { useState, useCallback } from 'react'; function UseCallbackExample() { const [increment, setIncrement] = useState(0); const val = useCallback(() => { setIncrement(counterIncrement => counterIncrement + 1); }, [setIncrement]); return ( <div> <p>You have clicked {increment} times.</p> <button onClick={val}> Click Here! </button> </div> ); } export default UseCallbackExample;
The memoized function created in the example above uses the useCallback hook. To avoid recalculating a value, think of memoization as caching it. This enables us to separate resource-intensive operations so that they won’t launch on every render automatically. The function modifies when particular dependencies change, improving performance and avoiding the needless re-rendering of components.
Overall, the hooks simplify the code by improving the performance, developer experience, and reusability. In addition, hooks have modified the developer’s approaches to writing and executing the code by providing flexibility and better-organized approaches, making it an essential tool.
How Can You Use Hooks in React?
Several types of hooks in React enable developers to create their applications efficiently and easily. This section will delve into six commonly used hooks. The state hooks and effect hooks are the most commonly used in React.
State hooks enable the addition and update of the state to the functional components. The developer can use State hooks by importing the React library’s useState hooks. Once we have imported the useState hook, we will call it inside our component by passing an initial state value, giving an array as an output. An array will contain two components: the current value of the state and the setter function to modify the state.
Effect hooks enable developers to execute the side effects within the functional components by getting the data with the help of an API or modification of the document’s title. The developer can use effect hooks by importing the React library’s useEffect hooks. Once we have imported the useEffect hook, we will call it inside our component and provide a function that defines the effect. All subsequent rendering of the component will call this function. developers can utilize as many hooks as they want within the same component, which enables them to bring numerous states and execute numerous side effects.
To use Hooks efficiently, it is crucial to adhere to a few guidelines:
- We cannot utilize hooks in class components as they are primarily made for functional components.
- Hooks should not be called inside loops, conditions, or nested functions, as this may result in unexpected behavior. When you avoid this, hooks are called in the same order each time a component renders. Instead, hooks are best utilized at the top level of a component, and conditionals can use the returned values.
These guidelines will help you use hooks effectively and maintain the functionality and efficiency of your application. Additionally, it’s crucial to keep in mind that hooks will only function in React function components; as a result, when you need to include state or side effects in a class component, either use class-based components or consider converting them to function components.
Hooks are an essential tool that enables developers to create an effective and dynamic application by making it efficient, reusable, and easy to understand. This section will explore the types of hooks and provide examples of their implementation. Following are the types of hooks in React.
1. useState
The useState hook enables developers to add and modify the functional components by managing the state within the components. The useState hook returns a current state and the function that modifies the state.
The state includes objects and arrays as one of the types of state. The useState hooks optimize state management within the functional component and improve the application’s performance by providing effective approaches to handling the state. Let’s look at an example to understand the useState hook better.
Start by importing the useState hook from the React library, and then we will call it inside the component by passing an initial value of 0. Now use a variable increment which is initialized as 0. The current state value would be increment, and the settler function is setIncrement.
By clicking the Click Me button, the state is modified with the settler function setIncrement, and the current state value increment is used to display how many times you have performed the clicks. Once the button has been clicked, the state value is saved, and the component is re-rendered to the settler function setIncrement to update it with a new value.
import React, { useState } from 'react'; function UseStateExample() { // Declare a useState variable "increment" // After declaring the variable, initialize it to 0 const [increment, setIncrement] = useState(0); return ( <div> <h4>You have performed {increment} clicks.</h4> <button onClick={() => setIncrement(increment + 1)}> Click Me </button> </div> ); } export default UseStateExample;
We have seen how a value gets increased every time we click on a button using useState hooks. The useState hooks are simple and essential for handling state within the function components of React. It helps modify and add state by providing efficiency to the code and making it easier to understand.
2. useEffect
The useEffect hook enables developers to execute side effects within the functional components by fetching the data with the help of an API or modification of the title of the document.
Let’s explore an example for a better understanding of the useEffect hook.
Start by importing the useEffect hook from the React library. Once we have imported the useEffect hook, we will call it inside the component by passing a function that defines the useEffect.
In our case, we are modifying the document title to return a display of how many times we have performed the clicks. The useEffect hook is executed after each component’s rendering, consisting of the initial and subsequent re-rendering.
Thus, the increment has been updated by re-rendering the component which performed that useEffect that modified the document’s title.
import React, { useState, useEffect } from 'react'; function UseEffectExample() { // Declare a usestate variable "increment" // AFter declaring the variable, initialize it to 0 const [increment, setIncrement] = useState(0); // Declare a useEffect hook which executes after each render useEffect(() => { document.title = `You have performed ${increment} clicks`; }); return ( <div> <h4>You have performed {increment} clicks.</h4> <button onClick={() => setIncrement(increment + 1)}> Click Me </button> </div> ); } export default UseEffectExample;
The useEffect is an essential tool for managing the side effects within the function component of React. The useEffect helps improve the performance, maintenance, and understanding of code.
3. useContext
Another commonly used hook is the useContext hook which enables us to access the context data inside the functional components. In React, useContext is a technique for sending the data with the help of a component tree without manually sending the props down at each stage.
Let’s see an example for a better understanding of the useContext hook.
Use useContext to initialize the context and call the React.createContext method, which takes the initial value as an input parameter. We are using a yellow background and white color as the initial value.
import React, { useContext } from 'react'; // Create a useContext hook const UseContextTheme = React.createContext({ background: 'yellow', color: 'white' });
The UseContextThemeButton component uses the context by calling the useContext hook with the context as a parameter. It will return the current context value, the blue background, and the white color property.
// This components utilized the context function UseContextThemeButton() { const themeButton = useContext(UseContextTheme); return ( <button style={{ background: themeButton.background, color: themeButton.color }}> I am a Use Context Theme Button </button> ); }
We now use the UseContextThemeProvider component to wraps its children in UseContextTheme.Provider by providing the prop value with a value of context.
// This components provides the context function UseContextThemeProvider({ children }) { return ( <UseContextTheme.Provider value={{ background: 'blue', color: 'white' }}> {children} </UseContextTheme.Provider> ); }
We now combine the above functions into one, so we can call it as a component itself.
// Function that calls all of the above functions function UseContextExample() { return ( <UseContextThemeProvider> <UseContextTheme_Button /> </UseContextThemeProvider> ); } export default UseContextExample;
A useContext hook is an essential tool for accessing the context data in the functional component of React. Furthermore, it helps optimize the code’s performance by preventing re-rendering every time the context’s value changes.
4. useReducer
The useReducer hook is an essential tool that enables us to handle the complex state logic inside the functional component. It is analogous to the useState hook. However, it gives more flexibility for determining how the state has been updated.
The following code demonstrates an example of the useReducer hook.
Start by making a function named incrementDecrement which takes two parameters: state and action. The modification to the state is described by the action, which is an object. In our case, add and subtract are two actions that increase and decrease the value.
import React, { useReducer } from 'react'; // Declare the incrementDecrement function function incrementDecrement(state, action) { switch (action.type) { case 'subtract': return { value: state.value - 1 }; case 'add': return { value: state.value + 1 }; default: throw new Error(); } }
The incrementDecrementCounter function uses the useReducer hook, which takes the incrementDecrement function and initial state as an argument. First, the initial state is declared as a value initialized to 0. Then, the useReducer hook returns the dispatch function and current state as an output.
The function dispatch uses the dispatch action, which results in state modification. Then render the add and subtract buttons along with the value.
function incrementDecrementCounter() { const [state, dispatch] = useReducer(incrementDecrement, { value: 0 }); return ( <> <h3> Value: {state.value} </h3> <p></p> <button onClick={() => dispatch({ type: 'add' })}>+</button> <button onClick={() => dispatch({ type: 'subtract' })}>-</button> </> ); } export default incrementDecrementCounter;
Clicking on the add button will increase the value by one, while clicking on the subtract button decreases the value by one.
In React, the useReducer hook is useful as it prevents unnecessary re-renders and helps maintain the code.
5. useMemo
The useMemo hook enables us to optimize by memoization the values and preventing unnecessary component re-rendering. It takes a dependency array and a function as a parameter. The function returns the value that must be memoized, whereas a memoized value lists dependencies in the dependency array. In addition, the memoized value is recomputed every time the value is changed.
The following code demonstrates an example of the useMemo hook.
The UseMemoExample component takes first, middle, and last names as a prop which uses the useMemo hook to retain the value.
The UseMemoApp component handles the state for the first, middle, and last fields. These fields store a person’s name once the text has been inputted. The state will be updated every time the value is modified in the input text with the help of the onChange event.
import React, { useState, useMemo } from 'react'; const UseMemoExample = ({ first, middle, last }) => { const Name = useMemo(() => { return `${first} ${middle} ${last}`; }, [first, middle, last]); return <h1>Welcome, {Name}!</h1>; };
export const UseMemoApp = () => { const [first, setFirst] = useState('John'); const [middle, setMiddle] = useState('Adam'); const [last, setLast] = useState('Doe'); return ( <div> <input type="text" value={first} onChange={e => setFirst(e.target.value)} /> <input type="text" value={middle} onChange={e => setMiddle(e.target.value)} /> <input type="text" value={last} onChange={e => setLast(e.target.value)} /> <UseMemoExample first={first} middle={middle} last={last} /> </div> ); };
The component displays a Name constant as an output which is the concatenation of the person’s first, middle, and last name.
In React, the useMemo hook enhances the application’s efficiency and performance.
6. Custom Hooks
Custom hooks enable developers to encapsulate and share the functionalities between the different components. Following is an example to demonstrate the custom hook that describes the implementation of the window’s dimension.
We make a custom hook called CustomHooksToCheckWindowDimensions which returns W and H of the window as an output where W is the width and H is the height of the window. We are using useState and useEffect hooks to determine the window’s dimension and modify the state’s value every time the window has been resized.
The CustomHooksToCheckWindowDimensions uses the useState hook to initiate the state value by attaining the inner width and height of the window using window.innerWidth and window.innerHeight properties.
The useEffect hook helps in monitoring the modification of the window’s dimension. Moreover, when the window is resized, the resizing function passed to addEventListener is invoked, which invokes setDim to reflect the new window size.
import React, { useState, useEffect } from 'react'; function CustomHooksToCheckWindowDimensions() { const [dim, setDim] = useState({ W: window.innerWidth, H: window.innerHeight }); useEffect(() => { function resizing() { setDim({ W: window.innerWidth, H: window.innerHeight }); } window.addEventListener('resize', resizing); return () => { window.removeEventListener('resize', resizing); }; }, []); return dim; }
Lastly, the CustomHookApp component calls the CustomHooksToCheckWindowDimensions, which returns the width and height of the window. The dimension of the window will be displayed as an output.
function CustomHookApp() { const { W, H } = CustomHooksToCheckWindowDimensions(); return ( <div> <h1>Dimension of the Window is:</h1> <p>Width: {W}</p> <p>Height: {H}</p> </div> ); } export default CustomHookApp;
Custom hooks allow you to handle various use cases like form handling and timers that were not possible before.
Advantages of Using React Hooks
This section will explore the advantages of using hooks. Following are the benefits of using hooks over class components:
Reusability and Conciseness of the Code
Using the custom hooks enable the encapsulation of logic and the reuse of the logic among numerous components, improving the modularity, comprehensibility, performance, and sustainability of the code. Moreover, employing hooks helps minimize the boilerplate code in creating components, which enhances the conciseness and makes the code easier to understand.
Better Performance
In React, hooks enable developers to optimize the components using various methods and approaches, including useMemo and useCallback, which helps enhance the application’s performance.
Improved Readability and Productivity of Developers
In React, hooks are an essential tool that enhances the comprehensibility of the logic flow and data present in the components, which leads to better readability and easier debugging. Moreover, it streamlines the development process by making the code and maintaining the components easier to understand.
Better Accessibility and Community Support
Encapsulating the logic for accessibility features in custom hooks and reusing it across your application is made simpler with the help of hooks. In addition to being a fully supported component of the React ecosystem, the hooks library has a sizable and active community of developers that actively collaborate and share knowledge and tools.
Better State Management
Hooks streamline component state management by encapsulating logic for updating and modifying state into discrete, reusable hooks.
Improve Sharing of Code and Simplified Testing
The logic in the hooks can be tested independently from the components that use them, which facilitates efficient unit testing. Moreover, custom hooks can share the code among the team members and facilitate the reusability of the code by working on a complicated project within a large group.
Hooks in React provide various advantages that enhance the code’s quality, performance, and maintainability and simplify the development process. With the help of hooks, an individual can create a dynamic, optimized, and scalable application on React.
Final Thoughts
React Hooks provide a robust and flexible approach to creating components in React. They enable simpler, more understandable, and easier-to-maintain code. By utilizing Hooks, developers can create complicated apps with less overall complexity and fewer lines of source code. They also offer a simple means of managing states amongst several components without needing class-based components or global state libraries like Redux. You must know how to use React Hooks to give in your full potential when developing applications.
If you enjoyed this, be sure to check out our other React articles.