React Hooks – 18 Months Later

Photo by Tatiana Rodriguez on Unsplash

The Scene

Time has passed quickly since the announcement of React Hooks at React Conf in 2018. It’s been 18 months for us working with React Hooks in production, and we have perceived a massive shift in the architectural front-end approach. 

React is one of the leading front-end frameworks and is well-known for its reusable UI components. The class components and UI (“dumb”) components are the building blocks of React. Class components manage their own state and life cycle. Handling and maintaining React components in large projects is challenging. 

Why React Hooks?

React Hooks have solved seemingly discrete problems. Hooks have touched different dimensions in our projects. It makes our code clean and better. We’ll see how implementing React Hooks creates a difference in our projects. 

  1. Before Hooks, we have used logic patterns in reusing the stateful logic. But these logic patterns such as render props and higher-order components require a restructured component.  These made the component complex by surrounding it with wrappers and made it more difficult to test.  
  2. As components turn more and more complex, understanding and maintaining them becomes difficult. The mix of logic between lifecycle methods increases the bugs and inconsistencies. Breaking the logic or testing those becomes difficult. Usually, separate state management libraries are used to manage the states.
  3. Creating classes in React is a barrier to learning. As functional components are widely used in React, the use of class components is becoming diminished. Classes provide you with state, but these classes may encourage anti-patterns leading to huge unbreakable components which logic can’t be reused. So code duplication occurs, and maintenance costs get sky-high.

React Hooks is designed to solve these problems. With Hooks, you can: 

  1. Split a component into discrete functions. 
  2. Reuse the stateful logic.
  3. Control the component lifecycle in a more intuitive way using abbreviated syntax. 

Initially, Hooks integration started as additions to existing functional components, but they are now gradually becoming a centric part of your project.

Top React Hooks

By implementing Hooks, you can access the class component features like state, context, effects in a stateless functional component. Different React Hooks are serving various purposes, replacing your Class-style component lifecycle logic and even providing advanced state management in the component level. 

We’ll now take a look at some commonly used Hooks.


A basic most-used Hook. It eliminates the difference between the functional components and stateless components. The Hook “useState()” alone changes the way functional components work. In a class component, a state is defined in the constructor and accessed using “this.state” while updating or setting the state. Hooks state to a functional component.  

import React, { useState } from "react";

export default function Button() {
  const [initialText, setText] = useState(
    "Click to change the text"

  function btnClick() {
    return setText("Text changed via Hook useState");

  return <button onClick={btnClick}>{initialText}</button>;



This saves the state and is used as an alternative for “useState()” in complex scenarios. A pure function reducer and the initial state is the input of the “useReducer()”. The function takes the current state and action, and it returns a state. As the next state depends upon the previous state, it is used in complex and nested objects.


import React, { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "Say Hello":
      return (state = "Hello");
    case "Say Bye":
      return (state = "Bye");
      return state;

export default function Button() {
  const [text, dispatch] = useReducer(
    "Say Something"

  return (
      <div> {text} </div>
      <button onClick={() => dispatch({ type: "Say Hello" })}>
        Click to say Hello
      <button onClick={() => dispatch({ type: "Say Bye" })}>
        {" "}
        Click to say Bye{" "}


The components in React are inter-related and are affected by data fetching, subscription or change of DOM elements. These effect on the components are referenced as “side effect”.
Before Hooks, lifecycle methods such as
componentDidMount, componentDidUpdate, and componentWillUnmount were used to update the DOM elements. With useEffect Hook, you can run the “effect” function after the changes in DOM. Using useEffect() Hook you improve performance, readability and eliminate repetition of code with less boilerplate. 

Below is a concise example. For more info & examples about useEffect, check out our recent post regarding useEffect and its various pitfalls.

useEffect(() => {
    prepareBehaviourOne(, handleStatusChange);
    return () => {
      releaseBehaviourOne(, handleStatusChange);

useEffect(() => {
    prepareBehaviourTwo(, handleStatusChange);
    return () => {
      releaseBehaviourTwo(, handleStatusChange);


That’s it for this time, more hooks and conclusions in our next post – stay tuned!

Drop your info here


Like what you see?

Sign up to our newsletter to get more tips,
best practices and helpful solutions
straight out from our own experience in the Front-end world.

We won’t spam you and won’t sell your email to nobody. Scouts promise!