Introduction to React Hooks

Learn via video courses

Overview

Hooks were first made available in React 16.8 in February 2019. React Hooks offer us other means to access features like lifeCycle, manage the state of your component, or perform an after-effect when specific changes are made to the state(s) without the need to create classes. This added feature can be useful for people who try to avoid classes. Hooks in React are available in a variety of types with different functions.

Introduction

If you dislike classes, hooks can be helpful to you. Without utilizing classes, hooks in react let you leverage React functionalities like state and lifecycle features. It allows you to connect function components to React's state and lifecycle capabilities, as the name would imply.

Because hooks are backward-compatible and do not operate inside classes, the scope for modifications is limited as of now. Therefore, it is entirely up to the developer whether or not to use them. Thanks to this new functionality, you can now use all React features, including the functional components.

Example using Hooks

In the example that follows, we will give our Counter component an internal state. Every hook appears as a call to a function inside our component method. This function acts as a link between the external world and the rendering code, which depends on a particular state.

Your component function's code still needs to render the component based on either its props or the values given by hooks. This is still its function. You must have faith in react as a developer for it to call your component function each time a fresh render is required.

We can see how to construct the same component using the standard class-base syntax in the code sample that follows. Take note of the unintended complexity increase. We must manage the fact that state updates are asynchronous, create a Constructor with a preset form, and isolate the initialization code from the rendering function.

Why Use Hooks?

In React, hooks address a wide range of issues that at first glance seem unrelated. Some of these issues may be familiar to you whether you are familiar with React already, use it frequently, or perhaps prefer another framework with a similar component style.

It is Hard to Reuse Stateful Logic Between Components

There is no mechanism to "attach" reusable behavior to a component in React (for example, connecting it to a store). If you have experience using React, you might be familiar with design patterns like render props and higher-order components that aim to address this. However, using these patterns necessitates reorganizing your components, which can be laborious and challenging to read.

A typical React application will probably be a "wrapper hell" of components encased in layers of providers, consumers, higher-order components, render props, and other abstractions as viewed in React DevTools. While DevTools allows us to remove them, this highlights a more serious issue, that is, React requires a better primitive for sharing stateful functionality.

You can remove stateful logic from a component using hooks so that it can be tested separately and used again. You can reuse stateful logic with react hooks without altering the component hierarchy. Sharing Hooks amongst numerous components or with the community is now simple as a result.

Complex Components Become Hard to Understand

We frequently had to maintain parts that began out being straightforward but turned into an unmanageable jumble of stateful logic and unintended consequences. Each lifecycle function frequently combines various unrelated pieces of logic. In componentDidMount and componentDidUpdate, for instance, components might fetch some data. The cleanup is done in componentWillUnmount, but the same componentDidMount method can also contain some unrelated logic that creates event listeners. Code that is related to one another and changes simultaneously is separated, but wholly unrelated code is merged into a single function. Bugs and inconsistencies can be introduced far too easily as a result.

Complex Components Become Hard to Understand

Due to the stateful logic's dispersed nature, it is frequently impossible to divide these components into smaller ones. They are also challenging to test. One of the reasons why so many people choose to combine React with a different state management library is because of this. However, doing this frequently provides too much abstraction, necessitates switching between multiple files, and makes it more challenging to reuse components.

Complex Components Become Hard to Understand-2

Instead of requiring a split based on lifecycle methods, hooks allow you to divide one component into smaller tasks based on what parts are connected (such as setting up a subscription or requesting data). To make the local state of the component more predictable, you can choose to manage it via a reducer.

Classes Confuse Both People and Machines

It has been discovered that classes can be a significant obstacle to learning React, in addition to making code reuse and organization more challenging. You must understand how this operates in JavaScript because it differs significantly from how it operates in most other languages.

The event handlers must be bound, and you must keep this in mind. The code would be much longer if ES2022 public class fields were not there. Props, state, and top-down data flow are concepts that people can grasp very well but still have difficulty understanding. Even among seasoned React developers, arguments over the distinction between function and class components in React and when to use each one arises.

Class components may induce unintentional patterns that force these optimizations to revert to a slower path. Classes are a problem for modern tools as well. Classes, for instance, make hot reloading erratic and unpredictable and do not minify well.

Hooks in react enable you to use more React capabilities without classes to address these issues. React components have always been conceptually more similar to functions. React Hooks embrace functions without abandoning React's pragmatic nature. You can access imperative escape routes using hooks without having to learn complex functional or reactive programming techniques.

Gradual Adoption Strategy

Developers working with React are primarily concerned with delivering products and do not have the time to look into every new API that is made available. Since hooks are so new, it might be best to hold off on using them for production purposes until there are more examples and tutorials available.

Importantly, react hooks coexist with current code so you can progressively implement them. Moving to Hooks is not being pushed right now. It is preferable to test them in new, unimportant components.

The official ReactJS documentation states that hooks are meant to cover all current use cases for classes. However, class components will continue to be maintained for the foreseeable future due to Facebook's extensive use of classes, which will not be replaced, and the fact that new code is being built using react hooks alongside classes.

useState

The useState hook, as its name suggests, enables you to use state in your function.

Let us begin by taking a closer look at how a class is used to maintain the state.

Here, items are initialized using this.state, and the state is updated using this.setState.

Replace this.state and this.setState with a single hook call when using the useState hook. The example above demonstrates this when using the useState hook to handle things.

The useState hook, as demonstrated by the example, initializes the state and offers a callback to update the state with a single line of code.

When to use- Use the useState hook to keep track of the internal state whenever a functional component needs to hold it. In other words, use the useState hook to provide stateful logic.

Syntax of useState-

The value of the initial state is the only input that the useState hook accepts.

It gives back an array with two elements:

  1. This array's first element, that is state, is a variable that stores the state's current value.
  2. The second element of the array, setState, is a function that inserts the new value into the state variable.

In the aforementioned syntax, the array components are assigned to the state and setState variables using the "Array Destructuring" syntax from ES6.

Theoretically, the following might be done to produce the same outcome:

However, the "Array Destructuring" ES6 syntax is advised because it is much simpler to comprehend, and a larger community uses the useState hook in this way.

How to Use the useState Hook

Let us create a simple `counter-example using the useState hook.

Add one to the counter each time someone clicks the "Increment by one" button. By controlling the count state in this component, this is made possible.

app.js

The useState hook should be used to set up the state.

There is an onClick handler for the button. Every time a click is made, this function calls setCount with the new count. The React library will update the state for the count and handle everything else.

To use the application, launch it.

Managing State for Multiple Values

A component needs an internal state for more than one value in many situations. A component with form elements is a typical example.

Start by looking at a class component that has two name and email input fields. In the constructor, specify the default values. You will depend on this later. To integrate state updates securely, use setState.

Try now to use hooks with the same example.

You do not have to merge two different values into one state variable when using the useState hook. Instead, utilize the useState hook to define as many state variables as necessary. React Fiber maintains track of each useState call separately in the background.

By utilizing the useState hook, the example above will seem like the code example below. You will see that using a hook to manage state is considerably more pleasing to the eye and easy to understand.

Two General Rules to Follow with Hooks

When using hooks, there are a few guidelines supplied by the React team.

Only Call Hooks at the Top Level

Only use hooks at the top level and avoid using them in conditions, loops, or nested functions. This guarantees that hooks are always called after each render in the same order. Because React depends on the sequence in which Hooks are used to know which state corresponds to a useState call, this is crucial (if you are using multiple). The sequence of your hooks could change from render to render if one of them is hidden away in a loop, nested function, or conditional, which would muddle up which state belongs to which useState.

Example:

Bad

Good

Only Call Hooks from React Functions or Custom Hooks

Simply put, it says that ordinary JavaScript functions should not invoke Hooks.

To make sure that these rules are applied automatically, React additionally offers a linter plugin.

Conclusion

In this react hook tutorial, we have covered the following points:

  • Hooks in react are a relatively new concept and have been incorporated into ReatJS since the React 16.8 update.
  • React hooks allow you to connect function components to React's state and lifecycle capabilities.
  • React hooks are backward-compatible and do not operate inside of classes.
  • React hooks are used to address a wide range of issues that might seem unrelated at first. Some of the significant issues that hooks in react address are:
    • It is hard to reuse stateful logic between components.
    • Complex components become hard to understand when using the Classes in react.
    • Classes confuse both people and machines.
  • React hooks are designed such that they are compatible with react classes, and their use is being gradually adopted. Also, react classes are going to be supported for the foreseeable future.
  • The useState hook lets you use state in your function.
  • There are generally two rules to follow while using hooks in react.
    1. Only call Hooks at the top level.
    2. Only call Hooks from React functions or custom hooks.
  • React hooks provide a very easily understandable and much cleaner way of writing code and require much fewer lines of code than using the traditional method of classes.