7

Will React Classes Get Deprecated Because of Hooks?

 3 years ago
source link: https://blog.bitsrc.io/will-react-classes-get-deprecated-because-of-hooks-bb62938ac1f5
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

React Hooks are a complete and better replacement for Classes. Will React Classes stay with us much longer?

2yQjq2z.png!web

Before you say anything, yes, I am aware that React’s official documentation states that there are no plans to deprecate class components any time soon, so don’t worry, you don’t have to go out and re-write your entire code.

“We intend for Hooks to cover all existing use cases for classes, but we will keep supporting class components for the foreseeable future. At Facebook, we have tens of thousands of components written as classes, and we have absolutely no plans to rewrite them. Instead, we are starting to use Hooks in the new code side by side with classes.” — React Docs [emphasis in the original text]

That being said, React has evolved since its first public version, just like the language it is built on has as well. So there is precedent and it makes sense that they would adapt to the latest trends, and here I’m just going to be covering that. Will my conclusion be right? I guess only time will tell.

Summary of the React’s evolution

As you may or may not be aware of, React only added hooks just recently (since version 16.8 to be more precise), but was it then when they added support for functional components as well? Not really.

Because React was conceived before ES6 was released, although components were already treated as classes, they had to be defined using an auxiliary method: React.createClass

This method would receive a literal object with properties for methods and the class-based component would be returned. This is what that looked like:

This is taken from an old version of React’s documentation, so you can see there are things such as the use of jQuery and the good old var keyword. Back then, that was the way to create your components, if you needed to, you could use the state property to handle stateful components just like you do now with newer class-based components.

With the next evolution came functional components , although they were stateless, they were perfect for simpler components. Because they were meant to be used as functions and not a weird mix between objects and functions (that being a possibility thanks to JavaScript’s data model), the this construct was out of the game, and thus, state was out as well. Class components that only needed a render method could easily be translated into a function returning the code of that method.

The following example shows you a functional component:

Familiar, isn’t it? Sadly, the lack of hooks prevented developers from taking full advantage of them. They did however, promised that functional components would be optimized in future releases, so even though at the beginning, these components had not much use, the long term plan might’ve been there all along (by the way, I’m talking about pre v15 here).

Around this time, ES6 was already a thing, and the React.createClass method was substituted for the now-standard Class syntax.

Finally, with version 16.8, the React team finally released Hooks, making functional components, not only just as great as class components, but simpler to write and potentially, better than their older brothers.

Currently, as a React developer, you have the option of choosing between Class components and Functional components (with hooks, of course), but which one is better? And is it worth it to invest in Class components considering the amount of effort the React team put into designing hooks for your functional components?

Pros and cons of Class Components vs Functional Components

While it is true that with the addition of Hooks into the mix, Functional components are just as capable as Class components — there are some minor differences.

From a verbosity point of view (for example), classes require you to write more code, simply because of the boilerplate needed by their syntax.

That’s not only a concern for large codebase. Code is written and maintained by humans. Verbose code tends to be harder to follow and understand than shorter and more concise code (that’s not always the case but that’s still a very reasonable rule of thumb).

Looking at a very basic example, you can see a trivial component defined below, using a class syntax:

Now, let’s look at the exact same component but using a functional approach:

Granted, you only managed to remove 6 lines, but it’s almost 50% of the code for the first component! Think about how much you can save in larger, more complex components!

Publishing and Reusing Components

As different libraries and frameworks make it possible for us to use React for pretty much anything (iOS, Android, desktop apps, static pages, SSR apps, etc.) we reuse our React components much more than before. That solves two challenges for us: speeding up development (by maximizing code reuse) and keeping a consistent UI across projects.

Writing clear and “lightweight” components becomes even more important than before. You want your team or even your future self, to be able to understand the code as quickly as possible so that it would be easily reused and maintained by others.

If you ever used a cloud component hub like Bit.dev , you know that well-structured components make all the difference in the world.

When you use Bit.dev to publish your reusable components, you do so from your app’s codebase and in parallel to building your app. You do not write a complete ‘component library project’ from scratch. You need your codebase to be as clear and modular as possible so that components could be easily published, used, and maintained by others.

uyM3Ejm.jpg Example: exploring React components published on Bit.dev

An Inherent Difference between Classes and Functions

There is another, less notable but more impactful difference between functional and class-based components. And instead of telling you about it, let me show it with an example:

QbqaIr3.gif

In case it’s not clear due to the quality of the GIF, here is what’s happening for each component:

  1. I click the “Alert” button, which should trigger an alert box 3 seconds later. The text for that alert will depend on the value selected on the dropdown.
  2. Before the 3 seconds are up, I’m changing the selected value on the dropdown.
  3. The final result on the alert box is the expected one for the functional component, but the class component is overwriting the value.

Let’s look at their code to understand what’s happening. Here is the functional component:

And here is the class component:

They render the same HTML, and they do the same thing, on a change event for the dropdown, they set a message on the state of the component and once the “Alert” button is clicked, the timeout is triggered. So why is their behavior different then?

The key here is on the functional component, can you guess what is it?

Spoiler alert!

It’s closures! That’s right, because of the nature of closures, everytime the component is re-rendered (whenever we update the state), a new function is created, but when the alert is fired, the older closures haven’t been destroyed, so the component alerts the correct message. However, because we don’t have the same closure for the class component, everytime we change the state and it re-renders, we’re forced to deal with the latest state. You can play around with the example in this codesandbox .

In other words, functional components capture the rendered value.

Sharing Logic is Easier with Hooks

Did you ever try to extract common behavior from different components in order to encapsulate it and share it with other components? There are ways of doing that with class components. But these ways are mere workarounds to the limitations that the class-based approach brings to the table.

Ever heard of Higher Order Components (or HOCs)? They’re just components created to wrap another component and expand their logic with extra code. In other words, you have to encapsulate generic logic inside a component just to make sure that when you wrap another component with it, that logic will be added to the target component. That’s a mouthful, isn’t it? Imagine having to code it or reading through a base code with this pattern applied.

How about render props ? This is another pattern that emerged and it consists of passing the encapsulated logic into components as part of their props. So you’re using props to add extra behavior to them. This produces code such as:

Personally, I think this is better than using components to wrap components, but still, it’s unclean and uses props to pass logic, which can be a bit dangerous if you don’t have full control over the code.

But now, thanks to hooks, you can encapsulate shareable logic using custom hooks, like so:

So, what do we have here? With a simple custom hook, we’ve properly encapsulated our custom logic and can cleanly use it inside any of our components. This is what a clean approach at sharing logic looks like.

It’s easier to add effect logic with hooks

When working with classes, in many cases we are forced to spread our effect logic across multiple lifecycle methods. That does the job — but not so elegantly.

Now, instead of using multiple lifecycle methods, you only need yo use one hook: useEffect that, as you’ve seen above, sets up a trigger that is executed when the component is rendered (by default, although you can adjust that) and a returned function that is executed when the component is unmounted.

To see an example, just refer to the above code, setting up the event listener for the mousemove event at the start and removing the listener when it’s no longer needed.

So, are you safe using class components in 2020?

I’d say you’re pretty safe for the time being, React is focused on giving their users the best experience possible. This is to say, considering classes are relatively new to the JS ecosystem and aren’t going away anytime soon, the React team will not drop support for them in the near future.

That being said, considering all the effort they’ve put on functional components and their corresponding hooks, it’s safe to say you should definitely start considering switching your mindset to start thinking about functions and hooks instead of classes.

The way I see it, newer versions of React might start adding features to functional components that are just not compatible with class-based ones, leave the latter to be a second-class citizen, just like the first ones were until version 16.8.

That is, of course, my educated guess, so what do you think ? Do you see this going down in a different way? Leave a comment down below and share your predictions!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK