React Hooks Basics

Hooks are upcoming features in React and are currently available in version 16.7.0-alpha.2. The hook can be used by installing the above version. 

npm i react@next react-dom@next

So, what are Hooks?

Hooks let you use React features without writing classes, they are functions that let you ‘hook into’ React state and life cycles from the functional component.

Note : Hooks don’t work inside classes.

Below we will see a simple example of the counter using both class and functional components with Hooks to grasp the concept of Hooks.

First, we will see the code for a counter component using class.

import React, { Component } from 'react'

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      count:0
    }
  }
  increaseCount = () => this.setState((prevState)=>({count :prevState + 1}));
  render() {
    const {count} = this.state;
    return (
      <div>
        <p>Number of clicks: {count} </p>
        <button>Increase Count</button>
      </div>
    )
  }
}

export default App;

Now, here is the code for a counter component using a functional component with Hooks.

import React, { useState } from 'react;

function App() {
  const [count, setCount] = useState(0);
  const increaseCount = () => setCount(count + 1)
  return (
    <div>
      <p>Number of clicks: {count}</p>
      <button>Increment Count</button>
    </div>
  );
}

export default App;

The first noticeable difference you’ll probably see is how much cleaner the code is for functional components with hooks compared to a class component.

In our class component, we have initialized a count state in the constructor and a function increaseCount in which we are using this.setState to increase the count state when we are clicking on the button.

While in our functional component, we have used the useState hook, which returns a pair of values such as a current state and a function that updates it. And it takes only one argument, which is the initial state. That’s why we write

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

where the count is a current state variable, which is similar to this.state.countand setCount is the function which updates the state, which is similar to this.setState and 0 is the initial value of the count state.

The square brackets used above are array destructuring, which is a JavaScript syntax. So, instead of using count and setCount, we could have used any other variable name such as

const [a, setA] = useState(0);

We can also declare multiple state variable in a single component.

const [a, setA] = useState(0);
const [str, setStr] = useState('test');
const [count, setCount] = useState(1);
const [obj, setObj] = useState({foo:'',boo:''})

Note from React documentation about the implementation of multiple state variables.

You don’t have to use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it.

We provide more recommendations on splitting independent state variables in the FAQ.

Now, we will look into another hook named as useEffect, which is used for performing side effects. It is like a combined componentDidMount, componentDidUpdate, componentWillUnmount. Below is the implementation for useEffect.

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

function App() {
  const [width, setWidth] = useState(window.innerWidth);
  const resizeWidth = () => setWidth(window.innerWidth);

  useEffect(()=> {
     window.addEventListener('resize',resizeWidth);
     return () => {
     // this will be used for clean up, same as componentWillUnmount
     window.removeEventListener('resize',resizeWidth);
     }
   },[]
    //empty array will ensure that useEffect will run only on mount
      and unmount
 )
  return (
    <div>
      <p>Width : {width}</p>
    </div>
  );
}

export default App;

Rules of Hooks

  • Hooks must be called only at the top level. Calling Hooks inside loops, conditions, or nested conditions is a BIG NO! as Hooks rely on call order. The explanation for above is given in: https://overreacted.io/why-do-hooks-rely-on-call-order/
  • Hooks must be called from React functional component or from custom hooks (will read about it in the next section). Hooks must not be called from a regular JavaScript function.

Custom Hooks

We can build our own Hooks, the advantage of building our own hook is that we can put shareable logic into reusable functions. A custom hook must start with ‘use’ so that it can automatically check for violations of Rules of Hooks, this convention is very important. For example, if we need the width state variable in the above code, in more than one component, we can convert it into custom hooks. Below we have made our useResizeWidth custom hooks.

function App() {
  const [count, setCount] = useState(1);
  const width = useResizeWidth();
  const increaseCount = () => setCount(count + 1);

  return (
    <React.Fragment>
      <div>
        {count} Width: {width}{" "}
      </div>
      <button onClick={increaseCount}>Increment Count</button>
    </React.Fragment>
  );
}
function useResizeWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  const resizeWidth = () => setWidth(window.innerWidth);
  useEffect(() => {
    window.addEventListener("resize", resizeWidth);
    return () => {
      window.removeEventListener("resize", resizeWidth);
    };
  }, []);
  return width;
}

From the above example, we can see our useResizeWidth() custom hook is a JavaScript function.

CodePen : https://codepen.io/bhavya2995/pen/pqdror

Reference : https://reactjs.org/docs/hooks-intro.html

excellence-social-linkdin
excellence-social-facebook
excellence-social-instagram
excellence-social-skype