After the React team announced the proposal of a new feature called Hooks at React Conf 18, there was a strange reaction in the React community: a flurry of tutorials describing how to use it, as if it was already in React core.
What is explicitly described as “a new feature proposal” was treated by some as a feature announcement. Clearly, there’s too much hype and “let’s rewrite everything right now” attitude, as Dan Abramov of the React team remarked:
So let’s take a chill pill, not even bother with the proposed API, and ponder how React got to this point.
If you’d rather see the code and refactor your app to use Hooks right now, the official docs are an excellent starting point.
In one of the first conference talks about React, Pete Hunt uses the word hooks to refer to methods of React.Component
, which allow the user to provide custom update logic — to hook into React’s internals and tweak their behaviour. The new feature proposal is introducing hooks in a similar sense — as a way of interacting with React by hooking your code into the React’s engine.
This idea of using functions instead of inheriting from classes plays well with the functional and declarative spirit of React. Because class-based components suffer from the old banana-gorilla-jungle problem, as described by Joe Armstrong:
the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.
With React.Component
, very often all you need is state or a ref, but what you get is a collection of methods you’ll never use and the necessity of writing the dreaded this
keyword (which is an anagram for you know what). Basically, Hooks are a proposal to ditch the classes and instead of inheriting from React, hook into React.
class
esThe class-based API of React has been a problem for some time now. The ES6 classes themselves are not really classes (just syntactic sugar masking prototypal inheritance), they don’t compose well, and the usage of this
keyword creates binding issues, especially when performing asynchronous operations.
So the search for class-less React development was on. Maybe the most notable project — now discontinued because of the introduction of Hooks — is recompose
(the first example in the docs is providing a state to a function component). However, recompose
is making heavy use of the Higher Order Component pattern, which unfortunately creates a hard to read and false hierarchy in the render tree.
Another example is Reactions Component
, which uses another very popular pattern for making the class components more composable — Render Prop. The problem here is that a user first has to be pretty familiar with class-based React API to make some sense of how Reactions Component
is to be used.
There are also cool projects that use the new ES6 Proxies to manage state, like react-easy-state
or — in a more lightweight and experimental way —react-recollect
. I recommend the article about the latter, which is a nice dive into how a super-readable and self-explanatory state management can be achieved. Sadly, the support for ES6 Proxies is far from ideal.
Currently, the Hooks implementation allows for replacing almost all of class-based component’s functionality (Hook equivalents for componentDidCatch
and getDerivedStateFromError
are to be added soon), so after they’re added to React, the search can be called off. Classes in React aren’t going anywhere anytime soon, but it’s clear that React team envisions a class-free future for the library.
The dichotomy between class and function components is an unnecessary burden for a user. I tend to regard a function component as a kind of lightweight little brother of the full-fledged class component — also, the distinction plays nicely with the presentational and container component pattern. But when I imagine learning React now, I think it’d be a bummer that a decision about using state or not (the most basic feature of React) has to be made before even starting to write the component.
It’s a bit like synchronous vs. asynchronous functions: async
/await
and Promise
s help us escape callback hell, but why should a programmer have to care if an operation is async or not in the first place? For me at least, Hooks are a much more understandable abstraction than class Something extends React.Component
— how do I know what’s lurking in the jungle that I have to bring along with the setState
functionality?
React prides itself on being declarative, but using lifecycle methods is quite imperative — a classic example is duplicated code in componentDidMount
and componentDidUpdate
methods. Using Hooks, that can be achieved with useEffect
function (there’s a great example of how Hook’s declarative API beats lifecycle methods’ imperativeness in the official documentation).
With Stateless Functional Components, React moved more in the direction of functional programming. Hooks are a move even further in that territory, as they enable building full-featured React apps without the use of classes, but with functions only.
When the proposal is finalized, it will be the biggest change to how React apps are developed since the launch of the library. Today’s nifty patterns like Higher Order Components or Render Prop will seem quirky or even hacky (because they introduce a false hierarchy). The familiar class App extends React.Component
with its list of lifecycle methods will be a thing of the past, and if it wasn’t for JSX syntax, a piece of code might not even look like a React component at a first glance.
But until then, let’s not get too attached to the proposed API and focus on writing code using cool, stable features.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowToast notifications are messages that appear on the screen to provide feedback to users. When users interact with the user […]
Deno’s features and built-in TypeScript support make it appealing for developers seeking a secure and streamlined development experience.
It can be difficult to choose between types and interfaces in TypeScript, but in this post, you’ll learn which to use in specific use cases.
This tutorial demonstrates how to build, integrate, and customize a bottom navigation bar in a Flutter app.