Learn how to convince colleagues to use React hooks in your full-of-classes project so that they become excited themselves

Categories React Hooks
Photo by Mael BALLAND

React hooks can be controversial. Some people are excited about them but others are cautious. Hooks are new and it is not clear if they will stick and whether they will not degrade the project qualities like consistency or performance.

But you are sure that hooks are the way to go. However, hooks cannot be used from classes and therefore you have to consistently only write functions. How do you convince others to stop writing classes?

If we use only functions the code is going to be more consistent. Someone may argue: we have class components everywhere, having both functions and classes is not uniform. Well, React has both functional and class components for a very long time. And they were always used together for different purposes. Functional components used to be presentational and we resorted to classes when we needed to use lifecycle methods or state. But now we can simply use functions and stop bothering with classes.

Functions are much more simple concepts. Classes, especially in JavaScript, are confusing as summarized here:

  • this binding: it is hard to remember and keep in mind how it actually works
  • Unused methods are not stripped out at compile time as its hard to tell which functions will be used.
  • If you have ever looked into the minified version of a react project file you might have noticed that component life cycle names are not minified.
  • Classes make it hard for hot reloading to be reliably implemented.
  • While prototyping and optimizing compiler to improve the performance of React components the React team found that classes encourage some patterns that make it a lot harder for compilers to optimize.

I just wanted to stress here that since functions are simpler and much more limited entities than classes it becomes easier for all sorts of tools to optimize them. I keep hearing about Svelte and it seems to be growing in popularity. This means React will have to keep up with the new world of ahead-of-time compilation libraries. However, classes make this problematic as react docs say.

Hooks perform just fine. React team even promises to make optimizations. From React docs:

  • In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.
  • Hooks avoid a lot of the overhead that classes require, like the cost of creating class instances and binding event handlers in the constructor.
  • Idiomatic code using Hooks doesn’t need the deep component tree nesting that is prevalent in codebases that use higher-order components, render props, and context. With smaller component trees, React has less work to do.

Hooks simplify code reuse. In software engineering discipline code reuse is one of the most important concerns. React did not include any special mechanism for that and we used just class and function composition known as render props and higher order components. These reuse patterns worked but caused a lot of pain in the form of wrapper hell:

In my previous post, we saw all the hassle we had to go through to have reusable parts with render props. We had to first render Period component which rendered PeriodicCounter which rendered Interval which finally rendered Starts or Rotor components. It’s a lot of syntactic noise and also a lot of useless nesting which complicates layouts. Starts and Rotor components do not have intrinsic parent-child relationships with Period, PeriodicCounter and Interval. They just need some stateful functionality from them.

Hooks solve code reuse problem elegantly. You just call plain old functions. Not only you do not have to wrap components into other components to be able to reuse stateful logic but also you can easily compose different hooks together without introducing wrapper hell.

Let’s have another look at usePeriod. We have user-defined hooks and we compose these hooks together by taking the output from one hook and passing it as an input to another hook. Just like functions do.

function usePeriod({ duration, stepEveryMs }) {
  const [count, step] = usePeriodicCounter(duration);
  useInterval({ stepEveryMs, step });
  return count;
}

Functional components with hooks are easier to understand. This might be subjective but here is what React team says:

Components might perform some data fetching in componentDidMount and componentDidUpdate. However, the same componentDidMount method might also contain some unrelated logic that sets up event listeners, with cleanup performed in componentWillUnmount. Mutually related code that changes together gets split apart, but completely unrelated code ends up combined in a single method. This makes it too easy to introduce bugs and inconsistencies.

To see how React hooks puts closer more related code, have a look at this visualization:

Also, using React hooks you do not manage the state of the application on your own. You do not have to declare a special state field in the class and have it managed with inherited methods (setState). Now the state conceptually leaves outside the component which just subscribes to the state changes and reacts to them. So, React is now more reactive 🙂

FacebooktwitterlinkedinFacebooktwitterlinkedin

Leave a Reply

Your email address will not be published.