Sunday, 6 October 2024

React Hooks - useCallback

 v useCallback Hook

Ø useCallback is a react hook that lets you a catch a function definition between re-renders.

Ø It means when we use the useCallback Hook, it doesn’t create multiple instance of same function when re-render happens.

Ø Instead of creating new instance of  the function, it provides  the cached function on re-render  of the component.

Ø useCallback hook returns a memoized callback function.

Ø Think of memoization as caching a value so that it does not need to be recalculated.

Ø The useCallback Hook only runs when one of its dependencies update.

Ø One reason to use useCallback is to prevent a component from re-rendering unless its props have changed.

 

Example -1 :

Step:1 Add below code in App component

 

import React, {useState} from ‘react’;

import ‘./App.css’;

import Header from ‘./components/Header’;

 

function App() {

           const [count, setCount] = useState(0);

return (

            <>

            <Header />

<h1>{count}</h1>

<button onClick={()=>setCount(prev=>prev+1)}>Click Here</button>

</>

)

}

export default App;

 

Step:2 Create new component under src/components/Header.js and add below code.

 

import React from ‘react’;

const Header =() => {

           console.log(“Header Rendered”);

return (

            <>

<h2>Header</h2>

</>

)

}

export default Header;


When render first time then Header component is render



Ø When click on button then also render Header component as seen in console.















Ø To restrict component rendering on button click use useMemo in Header component

 

import React from ‘react’;

const Header =() => {

           console.log(“Header Rendered”);

return (

            <>

<h2>Header</h2>

</>

)

}

export default React.memo(Header);

 

Step: 3 Add new function in App component, pass this function as props in Header Component.

 

import React, {useState} from ‘react’;

import ‘./App.css’;

import Header from ‘./components/Header’;

 

function App() {

           const [count, setCount] = useState(0);

           const  newFn = () => {}

return (

            <>

            <Header newFn={newFn} />

<h1>{count}</h1>

<button onClick={()=>setCount(prev=>prev+1)}>Click Here</button>

</>

)

}

export default App;

 

It will again render Header function, which is not required because we are not changing anything in Header component, and it is happen because referential equality.


Ø So as in below example in console two have same function returning value but when compare it gives false this is because both function located at different memory location.so both are not same function. So in same way when re-render components, it’s create new instance of this function.so every time we passing function as a prop as a new function.so props are changing that’s reason it will re-render Header component.

 

So here when we click on button that’s update count, so it’s state is changing and it will re-render App component, so when App component re-render it will again create new instance of newFn, which will mouting in Header component.so in Header component in every render we are passing new function which is different.so now we can solve by using useCallback Hook.





Ø To use useCallback hook

Step 3 update below code in App component.

 

Here, useCallback will not create another function, it will use the cached function. whenever it will create the function first time & it will catch that function in the memory and whenever  re-renders happen it will use that cached function, so the function will be the same and when function will be same, then header function props is same , so there is no change in props, so when props is not changing header will not re-render. Header component renders only once.

 

import React, {useCallback, useState} from ‘react’;

import ‘./App.css’;

import Header from ‘./components/Header’;

 

function App() {

           const [count, setCount] = useState(0);

           const  newFn = useCallback(()=>{},[])

return (

            <>

            <Header newFn={newFn} />

<h1>{count}</h1>

<button onClick={()=>setCount(prev=>prev+1)}>Click Here</button>

</>

)

}

export default App;


Ø If you want to call function when count is changed, then update below line

        const  newFn = useCallback((count)=>{},[count])




Sunday, 29 September 2024

React Hooks - useMemo

 v useMemo Hook

Ø The React useMemo Hook returns a memoized value.

 

Ø It’s like caching a value so that it doesn't need to be recalculated.

 

Ø The useMemo Hook only runs when one of its dependencies update. This can improve performance.

 

Ø The useMemo and useCallback Hooks are similar. The main difference is that useMemo returns a memoized value and useCallback returns a memoized function.

 

Ø The useMemo Hook can be used to keep expensive, resource intensive functions from needlessly running.

 

Example: 1 Why we need useMemo Hook (Problem without useMemo Hook)

import React, { useState } from ‘react’

import ‘./App.css’

 

function App() {

           const [number, setNumber] = useState(0)

           const [counter, setCounter] = useState(0)

 

           function cubeNum(num) {

            console.log(‘Calculation done!’);

            return Math.pow(num,3)

}

const  result  = cubeNum(number);

return (

            <>

<input type=”number” value={number} onChange={(e)=>{setNumber(e.target.value)}} />

            <h1>Cube of the number : {result}</h1>

<button onClick={()=>{setCounter(counter+1)}}>

Counter++</button>

<h1>Counter : { counter }</h1>

</>

)

}

export default App; 

so if you are click on Counter++ button then also it will called cubeNum method, because of when we update the counter ,changes the counter number, it re-render web page, it recalculate cube.so to prevent the function to recalculate cube, we can use useMemo hook.



import React, { useState, useMemo } from ‘react’

import ‘./App.css’

 

function App() {

           const [number, setNumber] = useState(0)

           const [counter, setCounter] = useState(0)

 

           function cubeNum(num) {

            console.log(‘Calculation done!’);

            return Math.pow(num,3)

}

//const  result  = useMemo(()=> {return cubeNum(number)},[number]);

const  result  = useMemo(() => cubeNum(number),[number]);

return (

            <>

<input type=”number” value={number} onChange={(e)=>{setNumber(e.target.value)}} />

            <h1>Cube of the number : {result}</h1>

<button onClick={()=>{setCounter(counter+1)}}>

Counter++</button>

<h1>Counter : { counter }</h1>

</>

)

}

export default App;

 

    When click on Counter++ button

    When 3 entered in textbox ,then only called cubeNum method



React Hooks - useRef

        Ø useRef is a react Hook that allows us to create mutable variableswhich will not re-render the component.

Ø The useRef Hook allows you to persist values between renders.

Ø It can be used to store a mutable value that does not cause a re-render when updated.

Ø It can be used to access a DOM element directly.

Ø useRef() only returns one item.

Ø It returns an Object called Current

Example:1 update count value

    Below example shows that if you use useEffect then it will goes infinite loop.

 

import React, {useState} from ‘react’;

import ‘./App.css’;

 

function App() {

           const [value, setValue] = useState(0);

           const [count, setCount] = useState(0);

          

           useEffect(() => {

            setCount(prev=> prev+1)

})

          

           return (

                       <>

<button onClick={()=>{setValue(prev => prev-1)}}>-1</button>

                       <h1>{value}</h1>

<button onClick={()=>{setValue(prev => prev+1)}}>+1</button>

<h1>Component Render Count: {count}</h1>

</>

)

 }

To avoid above issue use useRef hook

import React, {useState, useRef } from ‘react’;

import ‘./App.css’;

 

function App() {

           const [value, setValue] = useState(0);

           const count = useRef(0);

 

           useEffect(() => {

            count.current=count.current+1;

});

 

           return (

                       <>

<button onClick={()=>{setValue(prev => prev-1)}}>-1</button>

                       <h1>{value}</h1>

<button onClick={()=>{setValue(prev => prev+1)}}>+1</button>

<h1>Component Render Count: {count.current}</h1>

</>

)

 }




Example :: 2

import React, {useState, useRef } from ‘react’;

import ‘./App.css’;

 

function App() {

           const [value, setValue] = useState(0);

           const inputElement = useRef();

 

           const btnClicked = () =>{

            console.log(inputElement.current);

            inputElement.current.style.background=”blue”;

}

 

           return (

                       <>

<input type=”text”  ref={ inputElement }/>

<button onClick={btnClicked}>Click Here</button>

</>

)

 }

 

 After use console.log(inputElement);


    After use console.log(inputElement.current);



    After apply style with background color to blue    





 

        




React Hooks - custom Hook

  v CustomHook Ø React allows us to create our own hook which is known as custom hook. Example – 1 localStorage Demo Step-1 Create ...