Why hooks are the best thing to happen to React
React is the most popular front-end framework in the JavaScript ecosystem. It is famous for its ease of use and its readability, allowing companies and startups to adopt it. But classes can be unwieldy and hard to understand. Hooks allow you to use state, lifecycle methods, and other functionalities of React without using classes.
This article will explain what hooks are, what makes them unique, and why they are the best thing to happen to React.
The origin of React hooks
Originally, React mainly used class components, which can be strenuous at times as you always had to switch between classes, higher-order components, and render props. With React hooks, you can now do all these without switching, using functional components. Hooks make React so much better because you have simpler code that implements similar functionalities faster and more effectively. You can also implement React state and lifecycle methods without writing classes.
Below are code examples to illustrate React class and functional components.
import React, { Component } from 'react'
export default class Hello extends Component {
render() {
return(
<div>
Hello World!
</div>
)
}
}
The code above is a class component that prints “Hello World” in the DOM.
import React from 'react'
export default function Hello() {
return (
<div>
Hello World!
</div>
)
}
The code above is a functional component that prints “Hello World” on the DOM.
Comparing both sets of code above, the functional component has significantly simpler code that performs the same function; there’s no need to allocate space to a class instance, then call a render()
function, you just call the function. React hooks have so many benefits and functions they perform, but one of the big ones is to make the React lifecycle methods easier.
NOTE: You cannot use React hooks on class components.
How have hooks made the React lifecycle easier?
The various lifecycle methods in React include mounting, updating, and unmounting.
- Mounting inserts elements into the DOM.
- Updating as the name implies, updates elements in the DOM.
- Unmounting removes elements from the DOM.
Below is an illustration of the various React lifecycle methods:
Initially, you could only use these lifecycle methods with class components, which usually comprise a lot of carefully engineered code that is more difficult to write or understand than when you use hooks to implement them as functional components.
Take, for instance, if you try to fetch user data using a componentDidMount()
in a class component like in the code below:
import React, { Component } from 'react'
import Axios from 'axios'
export default class Hello extends Component {
constructor(props) {
super(props);
this.state = { name: ""};
}
componentDidMount() {
Axios.get('/api/user/name')
.then(response => {
this.setState({ name: response.data.name })
})
}
render() {
return (
<div>
My name is {this.state.name}
</div>
)
}
}
Now let’s compare it to doing the same thing with a functional component by using the useState
and useEffect
hooks in the code below:
import React, { useEffect, useState } from 'react'
import Axios from 'axios'
export default function Hello() {
const [Name, setName] = useState("")
useEffect(() => {
Axios.get('/api/user/name')
.then(response => {
setName(response.data.name)
})
}, [])
return (
<div>
My name is {Name}
</div>
)
}
The code above collects user data by using the Axios API and prints it on the DOM. The useEffect
and useState
hooks make for more straightforward and concise code that is easy to understand and work on than the class components. When using lifecycle in class components, the componentDidMount()
, componentDidUpdate()
, componentWillUnmount()
methods are handled individually, but when using React hooks, you can just do everything through the useEffect
hook.
Hooks have made React easier to learn for beginners
Class components have always been a little cumbersome and confusing, especially as it makes state management and code reuse look so much more complicated than it actually is. That made many beginner developers shy away from React and opt for an “easier” framework. With hooks, it’s now simpler to learn React; because of this, its use in the tech world today has grown:
The graph above shows the increase in the percentage of Stack Overflow questions about React over the years vs. other popular JavaScript frameworks, proving that its general usage has increased since the introduction of hooks.
Some hooks and their functions
Before hooks were introduced, organizing components by lifecycle methods forced us to sprinkle similar logic in several components i.e. writing the same code in several places. To solve this and other superficial problems, React embraced functions for more straightforward and more flexible code. The next issue they had to solve was how to change the state of our components. This now brings us to our first hook: useState
.
The useState
Hook
Arguably the most common React hook, useState
helps you pass in state variables in a functional component. Take a look at the code below:
const loadingTuple = React.useState(true)
const loading = loadingTuple[0]
const setLoading = loadingTuple[1]
loading // true
setLoading(false)
loading // false
In the code above, useState
takes a single argument: the state’s initial value. It returns an array with a state
variable and a function to update that state. You now have everything you need to update the state
of your functional component.
The next hook we will look into solves the problem of implementing lifecycles in a functional component. It’s called useEffect
.
The useEffect
Hook
The useEffect
helps to perform side effects in functional components; that is, any function that you need to run after updating the DOM. It replaces some events by running a function whenever one or more variables change. It takes two arguments: a function and an optional array. The function defines which “side effect” to run, and the optional array indicates variables, objects, etc., to watch for changes.
Other React hooks include:
useContext()
: This hook helps to build a context API, which itself is a mechanism used to share data without passing props.
useRef()
: This hook allows you to reference the DOM in the functional component directly.
Note: useRef()
doesn’t trigger a re-render like setState()
does.
useReducer()
: This stores the current state value. You can liken it to Redux.
useMemo()
: This is a hook used to return a memoized value, i.e. when you need your function to return a cached value.
useCallback
: This hook is used when you have a component’s child continuously re-rendering. It will then return a memoized version of the callback that only changes when one of the dependencies changes.
These are just some of the most commonly used React hooks. If you want to learn more about React hooks, you can check it out here.
Conclusion
We used classes for React components because it was the best way at the time as we couldn’t create a state or implement the lifecycle methods in functional components. React hooks have made performing these functionalities much easier by providing an avenue for simpler, more composable, flexible, and extendable code than using class components without hooks. Many companies have adopted React as their primary front-end framework, which makes more developers add it to their skill-set. If you have any questions, leave a comment below!
Tags: functional programming, react, react hooks
28 Comments
> The graph above shows the increase in the percentage of Stack Overflow questions about React over the years vs. other popular JavaScript frameworks, proving that its general usage has increased since the introduction of hooks.
The article does not mention when hooks were introduced, which was in 2018 according to the website (“today” is a bit weird for a feature introduced 3 years ago). Questions asked were already growing according to the graph, not declining in any way, so how is it that “more questions” correlates to “more usage because of the introduction of hooks which makes React more beginner-friendly”?
Where is the data to back up the idea that the introduction of hooks made more people want to use React?
Can it so easily be excluded the possibility of the declining of usage of the other 3 “competitors” moving to React (because of preferences/requirements) having an effect on the number of questions asked growing?
Overall, the entire “Hooks have made React easier to learn for beginners ” section makes a number of unfounded claims.
Agree about graph and last sentence.
In fact hooks is harder for beginners but overall it is better than classes. React is making new site though to make it easier for beginners to grasp hooks.
Why is it better than classes? Classes bring us very clear useful concepts:
– classes
– properties
– methods
These concepts help to name concepts and help to separate code properly. With class based components render() method was rendering, and each lifecycle point was a separate method.
Now everything is in single function and often is bigger mess than it used to. There is closure but it’s not clear where closure is stored.
Yes code can be a bit shorter now but typically because naming is simply removed.
As for making lifecycle simpler – it didn’t had to invent hooks – they could had simply renamed / changed lifecycle methods. At same point I can’t even feel that the new lifecycle methods ‘useEffect()’ is better at all. It completely lacks any kind of transparency as to when is this method being called.
Man, I agree so strongly that I will translate it to my language.
Por quê é melhor que classes? Classes nos traz claramente conceitos muito úteis:
– classes
– propriedades
– métodos
Isso ajuda a nomear os conceitos e separar o código apropriadamente. Com componentes baseados em classe o método render() está renderizando e cada ponto do ciclo de vida é um método à parte.
Agora tudo está numa única função e frequentemente mais bagunçado do que normalmente é. Existe o closure mas não é claro onde o closure é armazenado.
Sim, o código pode ser um pouco menor agora mas tipicamente por que os nomes foram simplesmente removidos.
Sobre simplificar o ciclo de vida – não precisava invetar hooks – eles podiam simplesmente renomear / mudar os métodos de ciclo de vida. Ao mesmo tempo nem acho que o novo método de ciclo de vida ‘useEffect()’ é melhor no fim das contas. Ele carece completamente de qualquer transparência sobre quando este método é chamado.
Definitely agree that the graph doesn’t indicate anything about how (un)helpful hooks have been (plus it doesn’t include Vue, which is a little confusing). And in my opinion hooks have made React more difficult to learn.
I do not like the `use` keyword that’s sprinkled into all of them and I think `useEffect` is very poorly named. Coming from lifecycle methods, it was very difficult for me to grasp for some reason but I think if it was just written as an event/change listener or a watcher then it would be much more clear. Something like `onChange([varThatChanges, otherVarToListenTo], () => {})` would make much more sense as it’s drawing attention to _what_ the function is listener for changes on and then showing what will happen when those change.
And lastly, I think hooks are overhyped and thus overused despite sometimes (not always) not providing additional value. One example would be something like [`useFetch`](https://use-http.com/#/). You could fire off a very simple vanilla JS `fetch` request and chain off of that but `useFetch` is often unnecessarily Reactifying it and making it slightly more complex. There are times when it can be helpful but I think its existence makes people more likely to get excited and reach for it.
I couldn’t agree more. I believe there is a time and place for everything. We need to use features of any framework judiciously and not simply follow the crowd.
Couldn’t disagree more with this article.
Descriptive naming makes it immediately clear what onComponentDidMount() does. When I learned React, I was able to read a component with this method and infer what it did and when it would be called, with no foreknowledge. It’s simply intuitive.
To know what useEffect() even means, let alone does, someone has to go to the documentation.
React hooks is the biggest source of bugs that I’ve seen in my career.
Lol, you have a big eyes xD
It’s also source of very difficult situations to explain to junior developers.
And even experienced developers often will struggle to notice bug in:
[count, setCount] = useState()
const increment = useCallback(() => setCount(count + 1)
A couple corrections that may help those confused:
* The “name” variable in the first hook example should be capitalized:
`setName(response.data,name)` should be `setName(response.data, Name)`
* This code:
“`
const loadingTuple = React.useState(true)
const loading = loadingTuple[0]
const setLoading = loadingTuple[1]
loading // true
setLoading(false)
loading // false
“`
… doesn’t actually work. The value of the const variable “loading” is not changing within the function invocation. The author meant this as pseudo-code; the next time the function is run, the value of “loading” will be false. Calling “setLoading()” triggers the function to re-run, which achieves the goal of re-rendering with the new value.
Not correct about this line: “`setName(response.data,name)` should be `setName(response.data, Name)`”
I think the original code has a typo and that it should be `setName(response.data.name)`. It looks like they put a comma instead of a period. The created `setName` function doesn’t take more than one parameter (I’m not sure what it would even do if it did).
The first example you use to compare functional vs class components really doesn’t do much to illustrate the advantage of functional components. In general I think it falls into the fallacy of assuming concise code is automatically better than explicit code. There are times where hooks lead to more sane, easy to read code. There are also times where I’d argue that class components do a better job of making the logic of a component clear, especially since all logic occurring during a lifecycle stage is wrapped up in a single method. Saving the 12 loc and few keywords in the example does nothing when pretty much any text editor handles code folding.
As other said the graph does nothing to argue that hooks have contributed to the rise of React, the rate of increase is the same.
In general this blog post strikes me as rather low-effort, with a bit of data taken from stack overflow post frequency to justify its existence, but doesn’t really go into any reason why one might prefer to use functional over class components. FWIW I do think that hooks are poorly designed in their current state, because of poor naming choices and because they’re not inherently intuitive like class components, but I do think that they’re the better pattern if you need finer control over your components’ lifecycle without introducing obsessive logic into every lifecycle method. Contrary to one of this blog post’s claims, I’d argue that class components are where new users to React should start, and hooks should really only be attempted once they’re familiar with the lifecycle already.
I do Javascript since 2005… I will give my honest opinions about react/hooks and all about the fashion trend of Lady Gaga.
This article seems to have been written by some react fanboy, with no data, and especially with no programing concepts:
– “the functional component has significantly simpler code than the class code”…. pardon me but seriously, I do not see a significant code difference, and most importantly less code does not mean necessary better or easier to understand
– “How have hooks made the React lifecycle easier?” pardon me again, how easier? … const [Name, setName] = useState(“”); –> what the hell is happening a magic variable and a magic setter appearing out of no where? how/when/why? I really hate magic in programming
– “The useEffect and useState hooks make for more straightforward and concise code that is easy to understand and work on than the class components….” help me please how can this useEffect and useState make this more straightforward…, what is using, what is that effect, how is using state, … sorry but for me the code must speak, the code must be the document to itself, as clean code states: “You know you are working on clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem. – Ward Cunningham” and this said it all about
I like React because is simple, with clear lifecycle methods, and easy to scale, but hooks… just another trend to sell something “cool”
When you react fanboys are gonna understand that React is just a rendering library, nothing more, if you stick putting more and more logic, controllers, models inside it, it means that you are spaghetifying your code (how the f… you can UNIT test a code inside the hook?). I have seen lot of React application rotting because of developers put everything inside the React components (even worst with functional components), loosing control of rendering cycles… and later blaming the smoke… “yeah we need to re-write from scratch with this new amazing library that solves our poor performance unscalable code”…
I would say there are two main advantages that hooks have provided, and they really have little to do with the hooks themselves. The advantage comes from the use of function components.
One, function components are much more concise. And two, it removes the need for the confusing `this` keyword (I’d like to see a chart on SO questions relating to `this` over time…). Hooks simply made functional components a viable option by giving them the same capabilities as classes.
As far as hooks being better than their class counterparts? I think its a wash. Hooks are much harder for beginners to pick up, especially `useEffect`. Hooks allow reusability of state logic unlike class state logic. `useState` doesn’t merge, leading to confusion for object value updates. Etc…
I think the addition of hooks is net gain for React, but I think this article misses the mark on why, and serves more as a quick overview of what hooks are.
In my opinion, what makes react hooks really shine is the fact that we can create custom hooks, which is a nice way to hide implementation details from components. A custom hook become responsible for doing whatever is needed to fulfil the contract expected by the component. On the other hand, the component will know only about the shape of the data the custom hook is providing and it is going to consume it according to its need.
You can’t create custom hooks. What you can do is – you can use hooks inside arbitrary functions. And IMHO this is terrible. Now code that is not supposed to be attached to react becomes fully attached to react. And now it’s not possible to know what hooks component is using just by looking at it, need to drill down.
Sorry but React hooks are one of the most overhyped, shortsighted, and badly magical concepts I’ve seen in programming in a long time. Frankly, I use mostly class components (coming from a Java, .NET, and iOS background) but also use hooks where it makes sense, but when the only thing you like is a hammer everything starts to look like a nail. And by having such a big fanboy base around hooks, popular React helper libraries are now being rewritten to use hooks heavily and treat class components as 2nd class citizens.
Problems with React hooks:
– Hooks appear to be designed and implemented by programmers that might be bright and skilled but that lacked the wisdom that many veteran software engineers have, and one of the things experienced programmers have is to AVOID MAGIC in code.
– Code in React hooks is everything but idiomatic. what the heck does “useEffect(() => {}, [])” tell you when you’re reading it without knowing it’s basically the equivalent of the obvious “componentDidMount()” method? They should have at least created an alias like “useMountEffect(callback)” for this.
– Hooks are initially misleading to people coming from functional programming background. Hooks ARE NOT functional programming, hooks are by nature IMPURE functions as they have side effects. To their defense, I assume that’s why they chose the name “useEffect”, possibly to imply the function is having side effects and is anything but functional programming.
– Class components might be a bit more verbose, but as other people have pointed out in the comments, they’re CLEARER, and they’re not that difficult or time consuming to write anyway. It’s like the classic mistake of giving variables cryptic values like “ttlOrdAm” instead of “totalOrderAmount”. Yes, the first one is shorter and quicker to write, but the latter will always be more understandable by everyone. Software code is written once, but read by others and yourself many, many, MANY times.
– One of their arguments for hooks is the class components are awful because you have to write code for both the “on mount” and “on update” events of a component when you want something to happen upon the component’s first load and subsequent renders, so they invented hooks to also alleviate this, when it’s as simple as putting that code in a separate method within the class and just calling it from both componentDidMount() and componentDidUpdate(), duh.
And what is the problem? The languages needed evolve, this is similar situation when the people let didn’t use Flash anymore, because already not useful to new technologies. You sound annoying with the new form to develop in react js.
This is not evolution though. This is devolution. You don’t really need all that magic that’s going on in react hooks to achieve good results. It’s a complicated technique that leads to very complicated bugs.
you either didn’t read the above comment or didn’t understand it at all. how can you compare language with library and with flash?
I see a lot of hate agains hooks here, but I consider using hooks much better than classes in React.
Benefits of hooks:
1. Much less boilerplate.
2. Separation of concerns, grouping by features (instead of grouping by lifecycles and state).
3. Functional approach (you just care about the inputs and output of hooks, with the entire logic inside the hook, while with classes the logic is scattered).
4. Really reusable logic, even in different components, including native ones (with a HOC you could achieve a similar result, but there’s too much magic happening under the hood, without the component knowing, which could cause all sorts of issues, including conflicting props and methods when more than 1 HOC is used, or when the base component changes, while hooks are explicit about the inputs and outputs).
5. No need to use ‘this’.
The problems I see with hooks are:
1. You can only call them at the top level of components (kinda expected due to its declarative nature used in an imperative context, so it’s a a small price to pay, but in the end it’s a rigid convention, including the ‘use’ prefix).
2. The dependencies array.
3. Performance penalty due to the lambdas created on every rerender.
4. A hook whose output changes often can cause lots of unexpected rerenders (although this could happen in a class that subscribe to events that happen often and change state).
Using the react hooks linter should solve problems 1 and 2 almost completely. As for problem 3, I hadn’t seen any noticeable difference in my projects.
I wrote with more details at https://www.quora.com/Is-it-preferable-to-use-React-Hooks-instead-of-classes-If-so-why/answer/Lucas-Basquerotto
In most cases, the hate for hooks come from the change of paradigm from classes, but in my opinion the change was for the better (much better actually).
I think that in regards to separation of concerns, react hooks do the opposite, they encourage piling up everything into single function. Separation of concern should exist by feature sets as well as per lifecycle or other technical concerns. What react hooks encourage is smushing different technical concerns into single function. It’s not like with class based components there was anything preventing anyone separating concerns. It even had benefit encouraging pretty decent pattern of doing stateless functional components and then class based components to manage the lifecycle and logic. Hook based approach no longer encourages stateless components because it’s just too easy to throw in state anywhere.
React hooks are a total bloater, they do not follow any of the SOLID or design patterns, what I have observed from my experience looking at hook usage in UI work here at amazon, is that code becomes totally unscalable, hard to read. All code becomes spaghetti. Once you develop a project with hooks, if you have to add new features, good luck, re-touch everything.
Example: Got to extend a project which was totally develop with hooks and context (as state sharing). In poor words what I had to do was show / select an additional information coming from the API in a table column, and reflect this information in some JSON as users selects the corresponding row. God knows how many commits it took, and how much files we changed just for this simple change.
React hooks seems to have blurred more the borders between UI and logic. React devs seems to have forgetten that React is just a VIEW and should stay like that. IMHO with classes it much cleaner on how my VIEW should update.
React hooks are a horrible solution to a problem, but with an incredibly successful marketing campaing.
They may have solved some problems, but have introduced a whole set of new ones. They are absolutely unintuitive to use, computationally inefficient and create new artificial difficulties that didn’t exist before: just try to replicate what you can do in a class constructor with hooks.
React hooks are the emperor’s new clothes of React, the thing that everyone feels forced to say “is cool” but internally knows is weird. The real good thing is that they are accelerating the dead of React in benefit of better frameworks.
Earlier React resorted to the use of class components which was difficult at times. You need to switch between components, classes, or render opps. With react apps all this is possible where there is no need to switch and use functional components See more at https://www.metasyssoftware.com/react-js-development/
When a new feature is added to a framework, and the number of questions on SO suddenly rises significantly, that might indicate something other than the frameworks popularity
“Hooks have made React easier to learn for beginners …”
Speaking as someone who learned React with hooks first, this is a bloody lie.
Class components made perfect sense to me from the jump. I look at one and it tells me exactly what its pieces do. The functional part is over here, and the stateful part is over here, and the names tell me when each function will execute. Simple and clean.
Looking at hooks, on the other hand, made my eyes cross. I still have to stop and slowly, carefully reason out what each hook is doing. The names are gibberish — useState at least makes sense, but the rest convey absolutely nothing — and don’t even get me started on custom hooks in the hands of a developer hustling to meet a deadline.