In the last article we talked about using lazy to asynchronously render web pages in order to optimise websites for optimum experience.
We talked about using suspense to render any component while we are fetching the webpage and error boundary to take care of the error.
You can read all about it here amara.hashnode.dev/web-optimisation-in-react .
In this article we shall go a little bit further.
React.memo
React.memo is an easy to use Higher Order Function( it takes in a function as a parameter and returns a function).
React.memo, memoizes a function, it would not re-render a function if the present state and the next state are the same ( a lot like the shouldComponentUpdate lifecycle method ).
example
//App.js
import React from ‘ react';
import AnotherComponent from ‘/another-component;
class App extends React.Component{
constructor(){
super()
this.state = {
number: 0
}
}
render(){
return(
<AnotherComponent name = { Villanelle } age = { 26 } />
<p>number of clicks: { this.state.number } </p>
<buttononClick= {() =>this.setState({ number: number ++ })>increase</button>
)}
};
// another-component.js
import React from ‘ react ‘;
constAnotherComponent = ({name, age}) => (
<div> My name is : { name } </div >
<div> I am : { age } </div >
)
export default AnotherComponent;
explanation
In the examples above the App component uses a button that when clicked on increases the number instantiated in the state by one.
React works in a sort of way that when the state of a component changes it re-renders the component.
The AnotherComponent gets rendered by the App component, which implies that whenever the App component re-renders it renders the AnotherComponent again ( even though we are not getting a different value for the props and the component is going to be the same everytime ).
Now this might not look like a big deal as our another component outputs literally only two lines, but if it were a lot larger this could take a toll on the performance. Thankfully React.memo is here to save the day.
// another-component.js
import React from ‘ react ‘;
constAnotherComponent = ({name, age }) => (
<div> My name is : { name } </div >
<div> I am : { age } </div >
)
export default React.memo( AnotherComponent );
Wrapping the React.memo around our component memoizes the functional component and only re-renders if we have new props coming into the component.
The same logic works with Class Compoments.
The difference between a normal Class component and a memoizes Class component, is that instead of React.Component we use React.PureComponent.
useCallback
The useCallback hook is a tool in web optimisation that is used to memoizefunctions.
const App = () =>{
const [count , setCount] = useState( 0 );
constincreaseCount=setCount(count++);
constlogName = console.log( ‘Amarachi' );
render(){
return(
<div>Count :{ count} </div>
<button onClick = { incrementCount1}> increase count </button >
)}
}
explanation
In the example above we instantiated a pieces of state using react hooks, ( read about it here ) with valueof count1 with a button to increase it's valueby 1.
When we click button it changes the state which re-renders the app, and everytime it does this re-regenratesthe functions again, which can be evident in the fact that the console.log function re-runs ( even without new information ).
We can memorize the function by wrapping the functions in a useCallback hook.
constincrementCount= useCallback( () =>setCount(count++ ), [ count] );
constlogName = useCallback( () =>console.log( ‘Amarachi' ), [ ]);
explanation
The useCallback is a hook that takes two parameters the function we want to memoize and an array of the condition to re-run the function.
The incrementCount function would only re-run when the count state changes, and the log name has no dependencies, and therefore would not re-run even when the app re-renders.
useMemo
This is used to memoize a value from a function.
example
const App = () => {
const [count , setCount ] = useState( 0 );
constincreaseCount = setCount(count++);
constfindPercentageOutOf127 = () = > {
return( count / 127 * 100)
}
render(){
return(
<div> Count : { count} </div>
<button onClick = { incrementCount1}> increase count </button >