Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[React] useCallback #109

Open
mahfujul-helios opened this issue Mar 30, 2024 · 0 comments
Open

[React] useCallback #109

mahfujul-helios opened this issue Mar 30, 2024 · 0 comments

Comments

@mahfujul-helios
Copy link
Collaborator

useCallback

what is useCallback ?

useCallback is a React hook used to memoize functions, preventing unnecessary re-renders in functional components. When you define a function inline within a functional component, it's recreated on each render. This can lead to performance issues, especially when passing functions as props to child components.

how it's works ?

The useCallback hook in React is a powerful tool for optimizing performance by memoizing callback functions in functional components. When you call useCallback, you provide it with a callback function and an array of dependencies. React then returns a memoized version of the callback function, ensuring that it's recreated only if any of the dependencies change between renders. This memoized function maintains a stable reference as long as its dependencies remain the same, allowing it to be safely passed as a prop to child components without causing unnecessary re-renders. By using useCallback strategically, you can mitigate performance issues related to unnecessary function recreation, improving the efficiency of your React applications. However, it's essential to use useCallback judiciously and measure its impact on performance, as excessive memoization can lead to increased memory usage.

The useCallback syntax

This hook follows a very simple pattern for utilization. It takes two arguments: the function you want to memoize, and the dependencies array.

useCallback(function, dependencies)
const updatedFunction = useCallback(
  (args) => {
    //action goes in here	
  },
  [dependencies] 
);
  • The first argument is the function you want to memoize.
  • The second argument is an array of dependencies. The elements in this array are the values on which the function to be memoized depends. If any of these values change, the function will be recreated.

Note, if you omit the dependencies array, the function will be re-defined on every render.

When to use the useCallback hook

Now you understand how the useCallback hook can optimize your app, let’s see some use cases:

  • When you need to pass a function as props to a child component.
  • If you have a function that is expensive to compute and you need to call it in multiple places.
  • When dealing with functional components.
  • When you are working with a function that relies on external data or state.

Note: Given the scenarios highlighted above, it’s still important to weigh the benefits and drawbacks of the hook and use it judiciously only where needed.

Benefits of using the useCallback hook

There are several advantages attached to using the useCallback hook. Here are a few:

  • Performance optimization: This hook optimizes the performance of your application by preventing a series of unnecessary re-rendering in your components.
  • Restricting rendering of child components: The useCallback hook in React allows us to selectively render important child components in a parent component. By using the useCallback hook, we can create memoized functions and pass them as props to child components. This ensures that only the necessary child components are rendered and updated when specific actions occur, resulting in improved performance.
  • Preventing memory leaks: Since the hook returns the memoized function, it prevents recreating functions, which can lead to memory leaks.

A practical example of the useCallback hook

In this section, you will see how to use the hook. We will see how React.memo falls short in a Single Page Application (SPA) and the need for the useCallback hook.

In this simple application, we have a Parent component with the name Parent.jsx and three children components, namely Button.jsx, Title.jsx, and Display.jsx which all rely on props from the Parent component.

Bootstrap a new React Project using Vite

Let’s bootstrap a new project with Vite:

npm create vite@latest useCallback-hook --template react

Clean up the default folder structure

First, try to clean up the folder structure by removing styles and the asset folder. The purpose of this article is to explain the useCallback hook so I won’t be considering styling the web app.

Next, create a component folder inside the src folder. In the component folder, create four files – Parent.jsx, Title.jsx, Button.jsx, and Display.jsx.

The file structure:

src
└── component
    ├── Parent.jsx
    ├── Title.jsx
    ├── Button.jsx
    └── Display.jsx

The Parent.jsx content:

// Parent.jsx

import React, { useState } from "react";
import Title from "./Title";
import Button from "./Button";
import Display from "./Display";

const Parent = () => {
  const [salary, setSalary] = useState(2000);
  const [age, setAge] = useState(30);

  const incrementAge = () => {
    setAge(age + 5);
  };

  const incrementSalary = () => {
    setSalary(salary + 100);
  };
  return (
    <div>
      <Title />
      <Display text="age" displayvalue={age} />
      <Button handleClick={incrementAge}>Update Age</Button>
      <Display text="salary" displayvalue={salary} />
      <Button handleClick={incrementSalary}>Update Salary</Button>
    </div>
  );
};

export default Parent;

The content of Title.jsx are as follows:

// Title.jsx

import React from "react";

const Title = () => {
    console.log("Title Component is rendered");
  return (
    <h1>useCallback Hook.</h1>
  );
};

export default Title;

The Display.jsx file contains the following:

// Display.jsx

import React from "react";

const Display = ({ text, displayvalue }) => {
  console.log("Display Component Rendered ", { displayvalue });

  return (
    <p>
      This person's {text} is {displayvalue}
    </p>
  );
};

export default Display;
Then, Button.jsx is as follows:

// Button.jsx

import React from "react";

const Button = ({ handleClick, children }) => {
  console.log("Button Component Renders - ", { children });
  return <button onClick={handleClick}>{children}</button>;
};

export default Button;

Finally, App.jsx contains these lines:

import Parent from "./components/Parent";

function App() {
  return (
    <>
      <Parent />
    </>
  );
}

export default App;

Launch the project on your browser by running these commands:

$ npm install
$ npm run dev

conclusion

The useCallback hook in React provides a means to optimize the performance of functional components by memoizing callback functions. By memoizing these functions, React ensures that they are recreated only when their dependencies change, thus preventing unnecessary re-renders. This stability in function references is particularly beneficial when passing callback functions as props to child components or when using them as dependencies in other hooks like useEffect. However, while useCallback can improve performance in certain scenarios, it's important to use it judiciously and measure its impact, as excessive memoization can lead to increased memory usage. Ultimately, useCallback is a valuable tool in the React developer's arsenal for enhancing the efficiency and responsiveness of applications, particularly in scenarios where optimizing function creation is crucial for performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant