React Hooks Tutorial In Simple Words
Today, we will enhance our ReactJS knowledge by looking into its another power which is React Hooks. React Hooks are introduced in 16.8 version. The interesting thing is React Hooks are not for classes. They are introduced to let us use React without classes. Confused? I was also confused when i encountered this statement. Without a wait, let’s understand it.
What are React Hooks?
Let’s first look into the definition of official React documentation:
React Hooks are functions that let us “hook into” the React state and lifecycle features from functional components.
Seems Complicated..Let’s understand it in simple words. React Hooks are functions that make functional components to work like Class components. When I started my journey of React, I wrote an article (link) in which I stated that ‘functional components’ are presentational components. They are meant for presentation like how you want your component to look. To change value of your data (to change state of functional component) and to use lifecycle features, we have to use Class components but react hooks changed the definition of functional components. It overcomes the limitations of functional components. Now, functional components are possessing the power of lifecycle features and state change. This lets us to use React without classes. I hope, now, you find React hooks little bit familiar but this is just a trailer. The main concern of every developer lies in the implementation. Why to wait for it, let’s go.
I would not cover every hooks as it’s not possible for me as I have not used every hook. I will write about basic hooks that is common to use.
BASIC HOOKS -
Here are two hooks on which I will write:
- useState — works like setState.
- useEffect — works like lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount).
For in depth knowledge of all hooks, refer official documentation(link).
Before introduction of above mentioned hooks, let’s learn its rules.
RULES OF HOOKS -
As I mentioned that hooks are normal Javascript functions but as we know there are always some rules for using anything. Hence, to use hooks — follow its rules -
1. Call hooks at the top level. Don’t call it inside loops, conditions or nested functions.
2. Call hooks from React functional components. Don’t call hooks from regular Javascript functions.
Just two rules that you have to keep in mind. Not a long list to remember.
Finally the time has come to understand your first React Hook.
State Hook — useState
Why I named sub-topic ‘useState’ as State Hook? The reason lies in its functionality. I hope you remember that hooks allow functional components to maintain its state (initialization and updation of state). ‘useState’ is that hook that does this.
‘useState’ is a hook that allows functional component to maintain its local state. In each render, react preserves the state. ‘useState’ returns us a pair -
1. First one is the value of your state like this.state.
2. Second one is function that you can use to update the value of first one just like this.setState.
Wait! Didn’t get it. No worry! I believe without example, it’s hard to feel the topic. So, let’s understand with the help of example.
1. import React, { useState } from ‘react’;
2. function DemoExample {
3. const [pageNum, setPageNum] = useState(0);
4. return (
5. <div>
6. <p> Page Number : {pageNum}</p>
7. <button onClick={() => setPageNum(pageNum+1)}>
8. Go to next page
9. </button>
10. </div>
11. );
12. }
Let’s understand the above example line by line (that’s why i have given numbering to the code).
Line 1 — This line shows how to import useState in your functional component.
Line 3 — This is important line which is telling us how to use this hook. Let’s break again into two parts — one is left of “=” and other is right of “=” to better understand this line.
3.1 — ‘useState(0)’ — 0 is initial state. This value can be number, string, array or your object like useState({ name: ‘anchal’ }). Unlike in class component, this.state needs to be object but here it can be anything (which i stated above). Hence, the argument in useState is initialization of your state.
3.2 [pageNum, setPageNum] — Here the concept of array destructuring comes. I will brief it here with an example.
Let’s assume an array ‘fullName’.
const fullName = [“anchal”, “nigam”]
To extract firstName and surName from it. We can use array destructuring concept.
const [firstName, surName] = fullName
// output –
// firstName = “anchal, surName = “nigam”
I hope this would have helped you to recall what array destructuring is.
Now, again come back to [pageNum, setPageNum] and also recall the statement which i mentioned above that is — ‘useState’ returns a pair. First variable is your state which you have initialized by passing argument to useState and other one is function to update it. Array destructuring gives us power to name it according to our use case. Here, ‘pageNum’ is one of our state variable and ‘setPageNum’ updates the value of ‘pageNum’ by 1 everytime when we click on the button.
One second! Don’t think that you are bound to use only one state variable. You can declare multiple state variables.
import React, { useState } from ‘react’;
function DemoExample {
const [pageNum, setPageNum] = useState(0);
const [usersList, setUsersList] = useState([]);
const [name, setName] = useState(‘anchal’);
const [userObj, setUserObj] = useState({name: “anchal”, country: “India”})return (
<div>
<p> Page Number : {pageNum}</p>
<button onClick={() => setPageNum(pageNum+1)}>
Go to next page
</button>
</div>
);
}
This is all about how functional components maintain its state.
Let’s move to other hook which is — useEffect.
Effect Hook — useEffect
Why we called ‘useEffect’ as Effect hook? I will not answer it now. You will get the answer by own after few seconds. First understand what effect (or usually called as side-effects) means in components. It is very common in a component to perform fetching data from api, subscriptions and updating the DOM. These are side-effects (or an action) that we perform. Lifecycle methods help in that like componentDidMount, componentDidUpdate, componentWillUnmount. As far we know functional components do not have these lifecycle methods to accomplish these tasks but still you are thinking that functional components do not have power to do these tasks?
Correct! You guessed right. ‘useEffect’ adds power to perform side-effects (or an action) in functional components. It behaves as componentDidMount, componentDidUpdate, componentWillUnmount lifecycle methods. The effect runs after every render including the first render.
Let’s understand each word with example -
import React, { useState, useEffect } from ‘react’;
function AnotherDemoExample {
const [pageNum, setPageNum] = useState(0);
const [employeesList, setEmployeesList] = useState([]);useEffect(() => {
fetch(‘http://dummy.restapiexample.com/api/v1/employees’)
.then((response) => response.json())
.then((response) => {
setEmployeesList(response.data)
});
});return (
<div>
<p> Page Number : {pageNum}</p>
{ employeesList.map((employee) => (
<p>{employee.employee_name}</p>
))
}
<button onClick={() => setPageNum(pageNum+1)}>
Go to next page
</button>
</div>
);
};
From above example, you can see we have initialized our state variable ‘employeesList’ to []. After that, we are using ‘useEffect’ to fetch data from api and updating the ‘employeesList’ state variable with the response of api. ‘useEffect’ behaved like componentDidMount. Isn’t? No. Let’s dry run this code to better understand.
If you will run this code then ‘useEffect’ runs. This will fetch the data from api and updates the state. You know after each updation, our component will again render then again ‘useEffect’ runs, again fetching of data -> updation of state ‘employeesList’ -> again rendering -> again fetching and boom! This cycle will never end. That’s why i said, it is not behaving like componentDidMount because componentDidMount is called only once but here ‘useEffect’ runs on each render. Wait! It seems I have confused you. Don’t stress yourself, solution is very simple. Rewrite above ‘useEffect’ like this:
useEffect(() => {
fetch(‘http://dummy.restapiexample.com/api/v1/employees’)
.then((response) => response.json())
.then((response) => {
setEmployeesList(response.data)
});
}, []);
Here, I passed second argument, an empty array. This makes ‘useEffect’ to run only once. Yes! You can pass second argument, an array. It looks into values of array and if any of the value changes then ‘useEffect’ runs. That’s why, I passed empty array to make ‘useEffect’ to run once. Look into below example to get better picture.
UseEffect runs once (behaves like componentDidMount)
useEffect(() => {
// statements
}, []);
UseEffect runs once ‘pageNum’ changes (behaves like componentDidUpdate)
useEffect(() => {
// statements
}, [pageNum]);
What’s say? Solution was easy na! I hope now my readers are clear but wait! I also mentioned ‘componentWillUnmount’. How ‘useEffect’ behaves like componentWillUnmount?
The answer is simple. Just return a function from ‘useEffect’. Look into the example.
UseEffect(() => {
return () => {
//statements that you want to execute before component unmounts like unsubscribing from any event.
}
});
That’s it! That’s all about this topic.
Congrats to my readers! Today, they have enhanced their ReactJS knowledge by learning another topic. I hope you understood the concept. I have tried my best to explain the topic in simple words as much as possible.
Thanks for reading! Will meet soon with another interesting topic. Till then you can read my previous articles.