— React, React Hooks — 4 min read
If you are new to Web Development or React in particular, you might have heard this buzz word "React Hooks" a lot and might be finding it overwhelming too. You may be having questions like – "Should I learn it? Is it important? Is it even required for a beginner like me?".
While I cannot straight away answer your questions, what I can do is help you understand why do React Hooks exist and what motivated their intoduction to React by the React Team.
Just so that we don't get overwhelmed with all the things that hooks have to offer, let's first define our goal for this article and we'll stick to it.
In order to answer why are React Hooks required, we will need to understand one thing: What problems do React Hooks solve?
To get a little context, let's see how React has evolved over the years. Initially when React was release, there was no concept of class in JavaScript and hence it had to be handled by React. Back then, the React Components were created using React.createClass
API as shown in the code snipped below.
1const ExampleComponent = React.createClass({2 getInitialState () {3 return {4 // ...5 }6 },7 componentDidMount () {8 // setup9 // add listener for feature 110 // add listener for feature 211 // and so on...12 },13 componentDidUpdate () {14 // logic to update state15 },16 componentWillUnmount () {17 // clean up18 // remove listener for feature 119 // remove listener for feature 220 // and so on...21 },2223 render() {24 return (25 // ...26 )27 }28})
With release of ES6, class
keyword was introduced in JavaScript and it was a new way to create classes in JavaScript. Later, React deprecated the createClass
API and moved to React.Component
API. Now we could create React Components using JavaScript native way of creating classes, as shown in the snippet below.
1class ExampleComponent extends React.Component {2 constructor(props) {3 super(props);45 this.state = {6 // ...7 };89 this.exampleFunction = this.exampleFunction.bind(this);10 }11 componentDidMount() {12 // setup13 // add listener for feature 114 // add listener for feature 215 // and so on...16 }1718 componentDidUpdate() {19 // logic to update state20 }2122 componentWillUnmount () {23 // clean up24 // remove listener for feature 125 // remove listener for feature 226 // and so on...27 },2829 exampleFunction() {30 //...3132 this.setState({33 // ...34 });35 }3637 render() {38 // ...39 }40}
With this change, React got better than earlier, but it still had some tradeoffs. Everytime while creating a component, it was compulsory to use constructor and call super(props)
and also .bind
every function using .this
keyword in the constructor.
Now these weren't too big of an issue and also these weren't actually React issues because this is how classes worked in JavaScript. But still, there had to be some more efficient way to overcome this problem.
Later, something called as Class Fields were released, which allowed us to directly add properties to the class, without having to use constructor and we no longer needed to .bind
any methods in the constructor as we could use arrow functions to create methods in class.
1class Example Component extends React.Component {2 state = {3 // ...4 }56 exampleFunction = () => {7 // ...8 }9}
Then with Functional Components, there was a simpler way to create components which did not require any state management or lifecycle methods. Initially, Functional Components were fairly simple. They would take in props and simply render a UI, no other complexity was involved.
1function ExampleComponent({ props }) {2 // ...3 render(){4 return(5 // ...6 );7 }8}
Now this was the stage, just before hooks were introduced. At this point, there was considerable scope of imporovement in the following areas:
State Management
Lifecycle Methods
exampleFunction
, while the logic of when to call exampleFunction
was contained in componentDidMount
and componentDidUpdate
methods.Non Visual Logic was not Reusable
These were the exact problems that motivated the introduction of React Hooks.
The React team introduced React Hooks to the world at React Conf in late October 2018. In early February 2019, they finally came in React v16.8.0.
React Hooks enables you to use state and other React features, without writing a class, in functional components. It gives combined advantage of Functional Components clean code and Class Components poweful features. And all this is possible because React Hooks are just regular JavaScript functions.
React Hooks provide a new way to add and manage state in functional components using useState
method. The useState method takes in the initial value of a state variable as the only argument and it returns array of two items, the first being the state variable and the second being a function to update that state variable.
1import React, { useState } from "react";23function App() {4 const [count, setCount] = useState(0);5 // count is state variable6 // setCount is method to update state variable count7 // initial value of count will be 0, as passed in useState89 return (10 <div>11 <p>You clicked {count} times</p>12 <button onClick={() => setCount(count + 1)}>Click me</button>13 </div>14 );15}
With Hooks, React introduces a new way to connect logic and it's trigger conditions. Instead of writing all the unrelated logic in a block of a lifecycle method which needs to be executed at a particular stage in lifecycle, we can now write any logic independently and pass in the trigger conditions with the help of useEffect
method.
useEffect lets us perform side effects inside a functional components. It takes two arguments, first being a function and second being an optional array. The function defines which side effect is to be run and the optional array defines when should the effect be triggered or re-run. The effect is triggered whenever the value of the variables passed in the array changes.
1import React, { useState, useEffect } from "react";23export default function App() {4 const [count, setCount] = useState(0);56 useEffect(() => {7 document.title = `You clicked ${count} times`;8 });910 return (11 <div>12 <p>You clicked {count} times</p>13 <button onClick={() => setCount(count + 1)}>Click me</button>14 </div>15 );16}
When it comes to sharing non visual logic across components, there is no inbuilt hook like useState or useEffect which can directly take care of it. But there is a flexibility of creating our own custom hooks, using the different inbuilt hooks as required. This lets us extract the logic out of the component and make it reusable across components.
An example of such logic is handling Authentication State. In apps with authentication, there may be number of functionalities where you need to check for authentication and only allow logged in users to access that functionality. In this scenario, you should not be required to write logic to handle authentication state in multiple components. You can write the logic once in custom hook and access it across components.
1import { useState, useEffect, useContext } from "react";23export default function useAuthListener() {4 const [user, setUser] = useState(null);56 useEffect(() => {7 // setup – add auth state listener8 // logic to handle auth state change9 // clean up – remove auth state listener10 }, []);1112 return { user };13}
I think, by now, you would have got a fair idea of how Hooks has enabled us to have better state management, concentrated effect logic and reusable non visual logic.
Since the scope of this article was to understand why are React Hooks required, I've taken the simplest examples of hooks and not gone into detailed explanation of how each of them works. While there is lot more about hooks that makes it powerful and there are many different ways in which we can use hooks, the content covered in this article is enough to answer our primary question: What problems do hooks solve, and why are they required?
I'll be writing in detail about different hooks, how they work and how can they be used in our projects, in future posts.
Thank you very much for reading this article. I hope you found it useful and if you did, please do share it with your friends or anyone who may find this interesting.
Connect with me on Twitter and LinkedIn to get updates on my new blog posts.