React Optimisation Using .memo, useCallback and useMemo
Use these concepts to give some relief to your react app.
Intoduction -
Let's Start with a fact Every time a parent component re-renders in react , the child component also re-render , regardless of the props or state changes. This way the unnecessary renders will make our react app slow and computational heavy.
In this article we will learn about three ways to make our react app optimized.
React.memo()
React.memo() is a higher order component which is used to skip the re-rendering , if the component props or state are not changed.
Let look at the following code - (Drag the black line to view code and preview together)
Here we have two state named age and salary. These states are shown in an Count component which is accepting these states as props . In Count Component we are doing console log of some text which will be printed every time the component render.
Now when we click on the increment_age button, it will increase the age state. But when we check the console , it show two outputs whereas there is only one state changed
Count for age
Count for salary
This is because whenever the parent component re-render(because one state got changed) the child component re-render unless we memoize the component.
Now to handle this, we use React.memo() in the export statement. This will memoize the component and when props or state of the component changes then only the component will re-render.
Check this one now -
Now when we click on the any button , only that component will re-render whose state got changed and not the both component which we can verify by having a look at console.
useCallback()
Now lets replace the button element with a Button Component which will accept a function as props to change the age and salary state. We will also use React.memo() to stop unnecessary re-rendering.
The new code will look something like this - (Drag the black line to view code and preview together)
Now when we change any one state(age , salary) , both Button Component will re-render which can be visualised by looking at the console. This is because every time the parent component render , the reference of the function which is being passed as props in Button Component, will be changed and thus even using React.memo() will not work as React.memo() will only stops the re-rendering if the reference address of previous render and the current render is same.
Now to let the React know that it is the same function we use useCallback , here we will pass two parameter one is the function itself and the second one is a dependency array. React do the shallow comparison of the elements in dependency array and if anyone of them got changed then the reference of the current function changes.
const incrementSalary = useCallback(() => {
setSalary((pre_state) => pre_state + 1000);
}, [salary]);
const incrementAge = useCallback(() => {
setAge((pre_age) => pre_age + 1);
}, [age]);
Lets see the updated code with the use of useCallback
Now when we change the state by clicking on the button , corresponding (whose state has got changed) component will re-render , but the Button Component will not re-render which can be visualised by looking at console as the console.log() statement of the Button component will be executed single time when the component render for the first.
useMemo()
Lets talk about a difference scenario other than above ..
Look at the below code ... (Drag the black line to view code and preview together)
When we try to increase Counter One Value it , you will see that , Counter One value does not changes quickly on the UI , because Fibonachi Function takes exponential time. But that does make sense because computing the fibonachi index of new index will take time.
Now when we try to increase the value of Counter Two, you will observe that this action is also not quick on UI, Although the Input for the Fibonachi index is same , as Counter One has not changed.
To Avoid these Heavy Repetitive Calculation we use useMemo. It will memoize the previous computed value and it will only do the re-computation when the element of dependency array which we pass in useMemo changes.
Now let's understand the updated code, which is shown below..(Drag the black line to view code and preview together)
Here we have memoized the output of the fibonachi function for the current Counter-One value. Clicking on the Counter Two button will change the state of Counter Two and that is reflected in the UI quickly. This is because , Now again the whole computation for the Fibonachi won't Happen.
So , These are the three ways which we can use to optimize the performance of the React App