Why React Hooks? A developer’s perspective.

Written by revanth0212 | Published 2019/03/02
Tech Story Tags: react | react-hook | javascript | design-patterns | reactjs

TLDRvia the TL;DR App

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class. — React Docs

As of React Version ≤ 16.7, if a certain component needs to have state and/or access to life cycle methods, it had to be built as a Class component since Functional components didn't have the concept of instances.

But with React 16.8, we have Hooks. This doesn’t mean Classes won’t work and also doesn’t mean that Classes will be deprecated. Hooks also don’t address all the features of Classes, there are certain pieces of the puzzle that are missing but the React core team says those will be addressed soon.

Motivation behind Hooks

The bar for learning and understanding a new paradigm without getting a significant benefit out of it is very high in the current IT world.

Reading the motivation section of the React docs didn't provide me with the right push needed for a transition. So I did a PoC (Proof of Concept) for myself. I will be going through each of the 3 points mentioned in the motivation docs with pseudo code from my PoC.

Our PoC will be a Facebooks feed component.

Sample Facebook feed mockup — https://www.behance.net/gallery/64942921/FREE-Facebook-PSD-Post-Mockup-2018

In the interest of time, let’s cut down the requirements for the component. It should be able to like the feed if someone clicks it and be able to comment when someone types and clicks enter in the comment box. Let’s not worry about the type of the like and share functionality for now.

We will be needing an internal state for this component. An initial look at the mockup reveals that we will be needing a state variable:

  1. To know if the feed is already liked by self. (likedByMySelf)
  2. To maintain the number of likes. (likes)
  3. To maintain comments. (comments)

It is hard to reuse stateful logic between components.

Let’s say these are our requirements:

When the user clicks on like button, likes should be incremented by 1 if likedByMySelf is false or decremented by 1 if likedByMySelf is true and then toggle the value of likedByMySelf.

When the user clicks on the comment button, comments input box should be highlighted.

After typing something, if the user clicks enter, a comment should be added into the comments state and the input box should be cleared.

With classes usually, we will be writing the action handlers inside the class as instance methods since they will be needing access to the internal state.

For instance:

2 days later if there is a new requirement to add like functionality to comments as well, we won't be able to reuse the onLike handler since it is tied to the Feed component and its state. To address such issues in Classes, we can use HOCs (Higher Order Components) and implement like and comment separately and wrap the Feed component with those HOCs. With HOCs we are separating unrelated state logic into different functions and injecting them into the main component as props.

But HOCs create wrapper hell. Instead of rendering just the Feed component, we will be rendering 3 components out of which 2 are wrapper components. This can be witnessed in the React dev tools when inspected.

With Hooks, we can solve this just like HOCs but without a wrapper hell.

useLikes and useComments have the same advantage of HOCs plus they don’t introduce wrapper hell.

2. Complex components become hard to understand.

With classes, there is no way to compose life cycle hooks. For instance, if we have to make network calls on the Feed component mount to get likes and comments to render.

Quickly the componentDidMount logic can get complex and for someone who reads this in the future, it is gonna give them some chills for a while.

Hooks solves this problem in a beautiful way. Hooks supports multiple life cycle hooks of the same type. For instance:

https://gist.github.com/revanth0212/1a4c949a70a98aae3cb7f0ed5775692c

Line 4 and 19 are componentDidMount life cycle methods in Hooks. If we consider useLikes for instance, it has state and componentDidMount life cycle hook. On mount, it will make the network call and immediately return current state. In the future, once the network call is resolved, the state is updated and likes will change. This will trigger a re-render of any component that uses useLikes hook.

Line 29 and 30 demonstrate life cycle hook composability feature with hooks. So now, we can have life cycle hooks written into custom hooks and let them maintain state locally and not worry about mount, update and un-mount logic. This makes code maintainability a wish and not hell.

3. Classes confuse both people and machines.

Well, I don’t accept the premise that Classes confuse people. They shouldn’t. We are developers and it is our duty to understand primitives that the language provides.

On the other hand, machines do get confused between Functions and Classes. For instance, minifiers/unglifiers have a hard time working with Classes.

Also, according to the docs, React team has been experimenting with Ahead of Time Compilation and good to have features like Component Folding but have realized that class components can encourage unintentional patterns that make these optimizations fall back to a slower path.

I personally have no grudge on Classes and can not comment on the 3rd motivation a lot. But if you guys have some thoughts, feel free to comment and let the rest of us know.

I hope this article makes a compelling case about the advantages of Hooks in React. Let us know if you are using Hooks and what are your favorite features in it.


Published by HackerNoon on 2019/03/02