Skip to content

C. useCallback

useCallback memiliki penulisan sama seperti useEffect, yaitu menerima 2 argument, argument pertama yaitu function yang dipanggil, dan argument kedua adalah depedency array

format penulisan
useCallback(fn, deps)

1. Penggunaaan useCallback

useCallback adalah salah satu hook yang di React yang digunakan untuk mengoptimalkan kinerja komponen dengan cara menghindari re-render function setiap kali komponen dirender ulang.

Dalam React, setiap kali komponen dirender ulang, function - function yang dideklarasikan di dalamnya juga akan dibuat ulang. Hal ini akan menjadi masalah dalam hal performace di aplikasi terutama ketika function tersebut digunakan sebagai prop untuk komponen lain.

useCallback digunakan untuk mengatasi masalah ini dengan cara memori caching (mengingat) function yang diberikan dan hanya membuat ulangnya saat dependensi yang ditentukan berubah. Ini membantu mengoptimalkan kinerja dengan mengurangi beban komputasi yang tidak perlu. Perhatikan contoh dibawah ini

Buatlah komponen User di folder module seperti gambar di bawah

Alt text

module/user.tsx
import { memo } from "react";
import Button from "../component/Button";

type UserProps = {
  users: string[];
  handleDelete: (index: number) => void;
};


const User = memo(({ users, handleDelete }: UserProps) => {
  console.log("render komponen user");

  return users.map((user, index) => (
    <li className="flex items-center justify-between" key={index}>
      <h1 className="capitalize">{user}</h1>

      <Button
        title="Hapus"
        colorSchema="red"
        onClick={() => handleDelete(index)}
      />
    </li>
  ));
});

export default User;

Kemudian ubahlah app/page.tsx menjadi koding di bawah

app/page.tsx
"use client";
import { useEffect, useState, memo, useCallback } from "react";
import InputText from "./component/InputText";
import Button from "./component/Button";
import Link from "next/link";
import User from "./module/User";

const Home = () => {
  const [users, setUser] = useState<string[]>(["ihsan", "faisal", "arriq"]);
  const [text, setText] = useState<string>("");
  const handleDelete = (index: number) => {
    setUser((user) => {
      user.splice(index, 1);
      return [...user];
    });
  };

  const handleAddUser = () => {
    setUser((user) => {
      return [...user, text];
    });

    setText("");
  };


  return (
    <section className="space-y-5">
      <User users={users} handleDelete={handleDelete} />
      <InputText
        placeholder="ketik "
        id="text"
        name="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <Button title="tambah" colorSchema="blue" onClick={handleAddUser} />
    </section>
  );
};

export default Home;

Jalankan di browser

Alt text

Kita lihat pada browser jika kita melakukan perubahan pada state text di komponenn Home maka komponen User akan dirender ulang. Terlihat pada console.log menampilkan pesan render komponen user. Hal ini tentu tidak boleh terjadi karena perubahan pada state text harusnya tidak membuat komponen User di render ulang. Komponen User akan di render ulang jika state users yang berubah. Untuk mengatasi hal ini kita bisa memberikan useCallback pada function handleDelete untuk mencegah pembuatan ulang function handleDelete ketika komponen Home di render ulang.

app/page.tsx
"use client";
import { useEffect, useState, memo, useCallback } from "react";
import InputText from "./component/InputText";
import Button from "./component/Button";
import Link from "next/link";
import User from "./module/User";

const Home = () => {
  const [users, setUser] = useState<string[]>(["ihsan", "faisal", "arriq"]);
  const [text, setText] = useState<string>("");
  const handleDelete = useCallback(
    (index: number) => {
      setUser((user) => {
        user.splice(index, 1);
        return [...user];
      });
    },
    []
  );
  const handleAddUser = () => {
    setUser((user) => {
      return [...user, text];
    });

    setText("");
  };

  return (
    <section className="space-y-5">

      <User users={users} handleDelete={handleDelete} />
      <InputText
        placeholder="ketik "
        id="text"
        name="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <Button title="tambah" colorSchema="blue" onClick={handleAddUser} />
    </section>
  );
};

export default Home;

Jalankan di browser

Alt text

Kita lihat pada browser , setelah memberikan useCallback pada function handleDelete maka ketika perubahan pada state text tidak akan membuat komponen User di render ulang.

Warning

Penggunaan useCallback harus memperhatikan kondisi-kondisi yang memang dibutuhkan. Tidak semua function harus dibungkus di dalam useCallback