Optimizing React.js Performance - A Guide to Effectively Use useCallback in Your Web Application
What is useCallback in Reactjs and how to use it to improve the performance of your Reactjs Web Application.
React's useCallback
is a hook in React that allows you to memoize a function. Memoization is an optimization technique that can help to avoid re-creating a function every time a component re-renders. This can be particularly useful when the function is passed as a prop to a child component, because it can help to avoid unnecessary re-renders of the child component. This means that the function will only be re-created if one of the dependencies has changed. This can be useful in a number of situations, such as:
- When you want to pass a function to a child component and you don't want the child to re-render every time the parent re-renders.
- When you want to avoid expensive calculations in a function that is called frequently.
Here's an example of how to use useCallback
:
import { useCallback } from 'react'
function MyComponent(props) {
// the function will only be re-created if props.dep changes
const myFunc = useCallback(() => {
// do something with props.dep
}, [props.dep])
return (
<div>
{/* myFunc will not change unless props.dep changes */}
<ChildComponent onClick={myFunc} />
</div>
)
}
In above example, myFunc
will be passed to ChildComponent
as a prop. If MyComponent re-renders, myFunc will not be re-created unless props.dep
has changed. This can help improve the performance of your web application by avoiding unnecessary re-renders.
Here is another example of how useCallback
can be used in a React component:
import { useCallback } from 'react'
function MyComponent(props) {
const { data } = props
const handleClick = useCallback(() => {
// Do something with the data
}, [data])
return <button onClick={handleClick}>Click me</button>
}
In this example, the handleClick
function will only be re-created if the data prop changes. This can help to improve performance, because the function will not need to be re-created every time the component re-renders for other reasons. You can also use useCallback
in Next.js a react.js-based framework.
There are other use cases where you can utilize React's useCallback
hook, such as fetching data using promises and updating the React state with the retrieved data.
import React, { useState, useEffect, useCallback } from 'react'
const MyComponent = () => {
const [data, setData] = useState(null)
// Define a function that returns a Promise to fetch data
const fetchData = useCallback(() => {
return new Promise((resolve, reject) => {
// Simulate a fetch request
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((data) => resolve(data))
.catch((error) => reject(error))
})
}, [])
useEffect(() => {
// Use the Promise to fetch data
fetchData()
.then((result) => {
setData(result)
})
.catch((error) => {
console.error('Error fetching data:', error)
})
}, [fetchData]) // Include fetchData in the dependency array
// Render the component with the fetched data
return (
<div>
<h1>Fetched Data:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)
}
export default MyComponent
The fetchData
function is wrapped with useCallback
to memoize the function and prevent unnecessary re-renders when it is used as a dependency in the useEffect
hook. The dependency array in useEffect
includes fetchData to ensure that the effect is re-run if fetchData
changes.
I hope this helps! Let me know if you have any questions.