React Hooks

·

4 min read

React Hooks

Hello World!

In this article let us see about the React functional components and the React hooks. Before diving into the Hooks, let us first see about the Stateful components and Stateless components.

Stateful Components vs Stateless Components

Stateless components are also known as Functional Components in React. It is a plain Javascript function that takes props as parameters and returns a React Component. Example:

import React from 'react';
export default function HelloWorld(props) {
    return <h1>Hello {props.name}!</h1>
}

Stateful components are also known as Class Components in React. It is a Javascript class extending React's Component class, that makes use of the render method which returns a React Component. Example:

import React from 'react';
export default class HelloWorld extends React.Component {
    render() {
        return <h1>Hello {this.props.name}!</h1>
    }
}

Components before hooks

Before the introduction of hooks, the class components were used in places where we need data other than that passed as props data. The state could be used only in class components. On the other hand, functional components are used in places where we require only props data. In simple words, the state cannot be used in functional components.

The lifecycle methods like componentDidMount() componentDidUpdate() componentWillUnmount() can be used only in class components and not in functional components.

The introduction of Hooks

Hooks are introduced as a part of React version 16.8. Hooks enabled us to use class component features in the functional component itself. Hooks are nothing but the functions that helps us to implement state and lifecycle methods in functional components.

Things to keep in mind while using hooks

  • React Hooks name start with 'use'. Example: useState useEffect useReducer
  • React Hooks can be used only in Functional components and cannot be used inside class components
  • Hooks can be used only on the top level of the components. Hooks cannot be used inside a conditional statement or a loop and cannot be nested inside a function.
  • Hooks can be used in a React component and not in a plain Js file.

The following are some of the hooks that are frequently used:

  • useState
  • useEffect
  • useReducer
  • useRef

Let us briefly discuss each of the hooks.

useState

The useState is the hook used to implement state in a functional component. Example:

const [randomNumber, setRandomNumber] = useState(0)

Here, randomNumber will be the name of the variable, setRandomNumber is the function that is used to set the state's value. The argument that is passed to useState would be the initializer. In our case, it is zero. If we try to print or display the random number, the value printed/displayed would be 0

We can change the state value just by calling the randomNumber method. Just like this

setRandomNumber(23)

Now, the value of randomNumber is been changed from 0 to 23

useEffect

The useEffect is the hook that is used to implement life cycle methods in functional components.

The useEffect takes two params, the callback function and the variable to which the hook is subscribed. The second parameter is not mandatory.

If we are not providing the second argument, the hook will be get executed on every DOM change.

Let us see how we can implement lifecycle methods in useEffect

ComponentDidMount: Passing an empty array as the second parameter will make the useEffect hook act like componentDidMount

// Hooks
useEffect(()=>console.log("ComponentDidMount.."), [])

// Method
componentDidMount() {
    console.log("ComponentDidMount..");
}

ComponentDidUpdate: We can achieve this by skipping the second parameter in useEffect.

If we want to subscribe to any particular variable, then we can pass in that variable as the second parameter. In this case, the hook will get executed only when some change happens in the variable passed as the second argument

// Hooks
// Will be executed whenever there is a dom change
useEffect(()=>console.log("Random Number: ", randomNumber))
// Will be executed only when there is a change in randomNumber
useEffect(()=>console.log("Random Number: ", randomNumber), [randomNumber])

// Methods
componentDidUpdate() {
  console.log("Random Number: ", this.state.randomNumber)
}

ComponentWillUnmount: We can achieve this by returning the function in the useEffect hook.

// Hooks
useEffect(() => {
    return ()=> {
        console.log("Component will unmount...");
    }
}, [])

// Methods
componentWillUnmount() {
   console.log("Component will unmount...");
}

We can use as many useEffects in a single component.

useReducer

This is similar to that of reducer in redux. This hook enables us to have greater control over the states. This is how it can be implemented

const [count, dispatch] = useReducer(reducer, 0)

Here, count is the variable, dispatch is the method used to access the reducer, reducer is the reducer function that takes in the action, 0 is the initializer.

Let us see an example for the useReducer hook

import React, {useReducer} from 'react';

export default function Counter() {
  const reducer = (state, action) => {
    switch(action) {
      case 'increase':
        return ++state
      case 'decrease':
        return --state
    }
  }
  const [count, dispatch] = useReducer(reducer, 0)
  return(
    <div>
      <p>Counter: {count}</p>
      <button onClick={()=>dispatch('decrease')} disabled={count<1}>Decrease</button>
      <button onClick={()=>dispatch('increase')}>Increase</button>
    </div>
  )
}

In the above example, we increase and decrease the count by passing actions to the reducer.

I have played with the React Hooks in this replit. Feel free to fork it and play around. Thank you and Happy Coding!