INTRODUCTION TO REACT HOOKS

“What is React? “

Does this question come to your mind? If yes, then let’s find out what it’s all about.

INTRODUCTION

React, created by Facebook, is an open-source JavaScript library for working on the frontend side, making the user interface for web or mobile applications. It is maintained by a well-established community of developers and companies. Some of the famous companies which use React are Facebook, Netflix, Discord, Amazon, Twitter, etc.

Now, let us find out what a Hook is in ReactJs.

Hooks are basic JS functions that are a new addition in React 16.8. They help us use state and other features without a class component. We can use functions to declare React state and lifecycle features. Hooks don’t work inside the classes.

Before working on Hooks, let me tell you about the Rules of Hooks:-

  1. Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.
  2. Only call Hooks from React functional components. Don’t call Hooks from regular JavaScript functions.

Well, there are many types of Hooks. We will go through the basic ones in this article.

The 2 basic hooks are:

  1. State Hook
  2. Effect Hook

There are a lot more advanced hooks. You can know more about them in the official documentation of React.

Setting up a react project

Prerequisites for React Hooks

  1. Node version 6 or above
  2. NPM version 5.2 or above

You can identify your node and npm version by using the following commands,

Now, here comes the command to set up a simple react project.

Command:

npx create-react-app <project-name>

STATE HOOK

It can be called inside a functional component and is used to add some local state to it. React preserves this state between re-renders. It is similar to this.setState found in a class component.

Let’s demonstrate how this.setState is used in the class component.

import React from 'react';

class CountClass extends React.Component {

  constructor(props) {

        super(props);

        // declare the state variable

        this.state = {  count: 0 };

  }

  render() {

        return (

          <div>

              {/* display the state variable */}

            <p><b>You clicked {this.state.count} times using class component</b></p>

            {/* update the state variable */}

            <button onClick={() => this.setState({ count: this.state.count + 1 })}>

              Click me

            </button>

          </div>

        );

  }

}

export default CountClass;

Below will be the output,

 

From the code above, we can see that the component's state is saved using this.state and it gets updated using this.setState when clicking on the button. As a result, the text inside the <p> tag also changes and shows the updated value.

Now, let’s see how we can implement this in the case of functional components using the useState Hook,

import React, { useState } from 'react';

function CountFunc() {

  // Declare a new state variable called count

  const [count, setCount] = useState(0);

 

  return (

        <div>

            {/* show the state variable in the webpage */}

          <p>You clicked {count} times using functional component.</p>

          {/* Button to update the state variable */}

          <button onClick={() => setCount(count + 1)}>

            Click me

          </button>

        </div>

  );

}

export default CountFunc;

Below will be the output:

The only argument that needs to be passed to the useState hook is the initial value of the state variable. In the above example, it is set to 0 for the count variable.

The initial state argument is only used during the first render.

useState returns a pair of value:

Current state value (count)

The state updater function that lets you update the state variable (setCount)

We can call this function from an event handler or somewhere else.

Declaring Multiple State variables

We can use the state hook more than once in a functional component.

  // Declare multiple state variables

  const [age, setAge] = useState(21);

  const [name, setName] = useState('Raj');

  const [todos, setTodos] = useState([{ text: 'Write Blogs' }]);

EFFECT HOOK

useEffect is one of the hooks of React, which runs the “effects” function after flushing changes to the DOM. By default, React runs the effects after every render (and the first render). React guarantees the DOM has been updated by the time it runs the effects. We declare effects inside the components, as we want to access the props and states.

useEffect can serve the same purpose as componentDidMount. componentDidUpdate and componentWillUnmount in React classes but is unified into a single API componentDidMount() is called after a component is mounted or rendered. If we need to load any data from a remote endpoint, we can make the request inside this.

componentDidUpdate() is called after componentDidMount() and can be useful to perform actions when the state changes. Inside it, we can have conditional statements and perform actions based on that.

 componentWillUnmount() is called before a class component is unmounted and destroyed.

Let's see an example where we can use useEffect in place of componentDidUpdate

Using Class

import React from 'react';

class EffectClass extends React.Component {

   

  constructor(props) {

        super(props);

        // declare the state variable

        this.state = {  showHiddenPassword: false };

  }

 

  componentDidUpdate(prevProp, prevState) {

        console.log('Prev state', prevState); // Before update

        console.log('New state', this.state); // After update

  }

 

  //  function to toggle the value of the state variable

  handleToggle = () => this.setState({ showHiddenPassword: !this.state.showHiddenPassword });

 

  render() {

        const { showHiddenPassword } = this.state;

        return (

          <div>

              <br/>

            <input type={showHiddenPassword ? "text" : "password"} />

            <button onClick={this.handleToggle}>Toggle hidden password</button>

          </div>

        );

  }

}

export default EffectClass;

 

Using function

import React, { useState,useEffect } from 'react';

const EffectFunc = () => {

        // state variable

        const [showHiddenPassword, setShowHiddenPassword] = useState(false);

 

        const handleToggle = () => setShowHiddenPassword(!showHiddenPassword);

 

        // function called on mount and when the variable `showHiddenPassword` gets updated

        useEffect(() => {

            console.log("Show password : ",showHiddenPassword)

          }, [showHiddenPassword]);

 

        return (

          <div>

            <input type={showHiddenPassword ? "text" : "password"} />

            <button onClick={handleToggle}>Toggle hidden password</button>

          </div>

        );

  };

export default EffectFunc;

Let's know more in details about the arguments passed to useEffect

What arguments are passed to useEffect hooks?

useEffect takes two arguments. The first argument passed to useEffect is the function (also known as effect) and the second argument (optional argument) is an array of dependencies

First argument

The first argument, called the effect, is the function which is executed when the component is mounted on the first render and whether it is executed in subsequent updates is determined by the array of dependencies passed as the second argument.

Return value of the effect argument

Effect takes no parameters, but it must return either a function or undefined. The returned function is called cleanup. Cleanup is performed before calling  the effect (to clean up effects from the previous render). Effect can also return undefined. So, it's not a surprising thing to see the effect without cleanup.

Second Argument

The second argument to useEffect Hook is an array of dependencies. We can choose when each effect needs to be executed after mounting the component. If one of the dependencies changes, the effect will be rerunned. We can do this by mentioning the values in the array of dependencies and pass the array as the second argument of useEffect.

React compares the current dependency value and the value on the previous render. If both are not the same, the effect is invoked. If the array is empty, then the effect runs and cleans up only once (on mount and unmount). This tells React that the effect doesn't depend on any values from the prop or state; hence, it never re-runs. In this case, the props and state inside the effect will always have their initial values. This process is similar to the componentDidMount and componentWillUnmount lifecycle, which also renders only once.

This is also an optional argument, and If we omit it, the effect will be executed after every render.

Using Multiple Effects in a component

useEffect can be used for different kinds of effects after a component renders. So, we can write multiple useEffects to separate the concerns.

We might have a case where an event listener needs to be added during the initial mount and further clean up at unmount or another case where a particular listener needs to be cleaned up and re-added on a prop change. In these cases, using two different useEffect is better to keep the relevant logic together and have performance benefits.

          useEffect(() => {

                // adding event listeners on mount here

                return () => {

                // cleaning up the listeners here

                }

            }, []);

 

            useEffect(() => {

                // adding listeners everytime props.x changes

                return () => {

                // removing the listener when props.x changes

                }

            }, [props.x])

       

       

CONCLUSION

Hooks are a great new addition in React 16.8. Hooks keep the related logic in the same place, making it less complicated and providing more excellent ergonomics for sharing stateful logic. Well, there are many more concepts to React Hooks. If you want to know more, go through the official documentation of React.

This blog has been submitted by Cyborg, NIT Rourkela under the Robocraze Club Outreach Program.

Author: Biswajeet Sahoo

Leave a comment

Please note, comments must be approved before they are published