useCallback vs useEffect: What is the main difference between them?

In React, both useCallback and useEffect are essential hooks that help developers manage their component’s behavior and optimize the performance of React app. In this blog, we will explain main the differences between useCallback and useEffect, their use cases. Also, we will try to provide you with simple explanations and practical examples. That will help you to understand the main difference b/w these Hooks.

1. Understanding useCallback: useCallback is a React hook used to memoize functions, optimizing performance by preventing unnecessary re-rendering of child components that rely on reference equality.

2. Understanding useEffect: useEffect is a React hook used to achieve React lifecycle? You can manage your component lifecycle events, like executing code when the component mount, unmount, or when specific dependencies are injections. Also, It allows you to perform actions such as fetching data, subscribing to events, or modifying the DOM.

useCallback vs useEffect Exploring the Differences Between

The selection between useCallback and useEffect hooks is determined by the scenario of your React component. If you want to understand the differences between the two Hooks we will assist you in making a good decision. Here are some guidelines to consider:

Use useCallback when
  1. When you want to avoid unnecessary re-renders of child components or API calls.
  2. You can pass callbacks as props to child components if you want to optimize the performance by memoizing the functions.
  3. If you want to optimize performance in scenarios where the callback function doesn’t depend on any external variables.
Use useEffect when:
  1. If you want to perform any side effects inside your component, such as fetching data from an API.
  2. You can manage your component lifecycle events, like executing code when the component mount, unmount, or when specific dependencies are injections.

Let’s take an example that demonstrates the use of useCallback and useEffect in a scenario with three tabs: “Employees,” “Managers,” and “Tech Leads.” When a tab is selected, the API parameters will change accordingly. Additionally, we’ll simulate an API call when creating an employee using the useEffect hook.

import React, { useState, useEffect, useCallback } from 'react';

const Tab = ({ name, selectedTab, onSelect }) => {
  const isSelected = selectedTab === name;

  return (
    <button onClick={() => onSelect(name)} style={{ fontWeight: isSelected ? 'bold' : 'normal' }}>
      {name}
    </button>
  );
};

const EmployeeList = ({ tab }) => {
  const [employees, setEmployees] = useState([]);

  const fetchData = useCallback(async () => {
    try {
      const response = await fetch(`https://api.example.com/${tab}`);
      const data = await response.json();
      setEmployees(data);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  }, [tab]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  return (
    <div>
      <h2>{tab} List</h2>
      {employees.map(employee => (
        <div key={employee.id}>{employee.name}</div>
      ))}
    </div>
  );
};

const EmployeeManagement = () => {
  const [selectedTab, setSelectedTab] = useState('employees');

  const handleTabSelect = useCallback(tabName => {
    setSelectedTab(tabName);
  }, []);

  return (
    <div>
      <Tab name="employees" selectedTab={selectedTab} onSelect={handleTabSelect} />
      <Tab name="managers" selectedTab={selectedTab} onSelect={handleTabSelect} />
      <Tab name="tech leads" selectedTab={selectedTab} onSelect={handleTabSelect} />

      {selectedTab === 'employees' && <EmployeeList tab="employees" />}
      {selectedTab === 'managers' && <EmployeeList tab="managers" />}
      {selectedTab === 'tech leads' && <EmployeeList tab="tech-leads" />}
    </div>
  );
};

export default EmployeeManagement;

In the above scenario, we have the Tab component that is responsible for rendering of each tab button. And the EmployeeList component will display the list of employees based on the selected tab State. Also We use the fetchData callback function, memoized with, useCallback to fetch data from the API endpoint based on the selected tab. The useEffect hook is used to trigger the API call when the component mounts or when the fetchData callback function changes.

The EmployeeManagementcomponent will render the tab buttons and the EmployeeList component based on the selected tab. The selected tab is managed with state and updated via the handleTabSelect callback function, which is also memoized with useCallback.

This example demonstrates how useCallback optimizes performance by memoizing the fetchData function and how useEffect triggers the API call to fetch data when the component mounts or when the fetchData function changes due to a tab selection change.