
Page Content:
1.Introduction
2.Syntax
3.Use-Case for useCallback
1.Introduction:
1.useCallback will return a memorized version of the callback that only changes if one of the dependencies has changed.
2.This is useful when passing callbacks to child components that depend on reference equality to prevent unnecessary renders.
2.Syntax:
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b]
);
Here, the doSomething() function will only be called again on the next re-render if the values of a or b change, otherwise only the cached version of the function is passed.
NOTE:
- The array of dependencies is not passed as arguments to the callback (arrow function). Conceptually every value referenced inside the callback should also appear in the dependencies array.
- useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
- useCallback() returns the function where as useMemo() returns the value.
3.Use-Case for useCallback:
Problem statement:
Let’s understand the below code without using useCallback hook, Here whenever the input number1 or number 2 changes it re-renders <Input1/> as shown below:
App.js:
import React,{useState} from 'react';
import Title from './Title';
import Input from './Input';
function App(){
var [number1,setNumber1] = useState(0);
var [number2,setNumber2] = useState(0);
function updateNumber1(){
setNumber1(number1+1);
};
function updateNumber2(){
setNumber2(number2+1);
};
return (<>
<Title/><br/>
<Input1 change={updateNumber1}/>
<Input1 change={updateNumber2}/>
</>);
}
export default App;
Title.js:
import React from 'react';
function Title(){
console.log("title updated");
return <>useCallback Hook </>
}
export default React.memo(Title); //memo used to render component
on props &state change
Input1.js:
import React from 'react';
function Input1(props){
console.log("input 1 updated");
return <input type="number" onClick={props.change} />;
}
export default React.memo(Input1); //memo used to render component
on props &state change
Result:
From the above video, you can clearly see that whenever any number1 or number2 changes it renders all instances of Input1 component but this is not the expected output. Here updateNumber1 function should only re-render first <Input1/> instance not second.
We can achieve this using useCallback as shown below:
<Title/> & <Input1/> are same as above.
App.js:
import React,{useState,useCallback} from 'react';
import Title from './Title';
import Input1 from './Input1';
function App(){
var [number1,setNumber1] = useState(0);
var [number2,setNumber2] = useState(0);
const updateNumber1 = useCallback(()=>{
setNumber1(number1+1);
},[number1]);
const updateNumber2 = useCallback(()=>{
setNumber2(number2+1);
},[number2]);
return (
<>
<Toolbar/><br/>
<Input1 change={updateNumber1}/>
<Input1 change={updateNumber2}/>
</>);
}
export default App;
Final Result: