Optimizing React.js Performance - A Guide to Effectively Use useCallback in Your Web Application

April 01, 2022 Dykraf

What is useCallback in Reactjs and how to use it to improve the performance of your Reactjs Web Application.

Web Story

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:

  1. 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.
  2. 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.

Topics

Recent Blog List Content:

Archive