Senin, 10 October 2022

Memahami Konsep Penggunaan useEffect Hooks dalam React

Bagi kita yang sering memakai react harusnya tidak asing lagi dengan namanya useEffect ini. Tetapi tidak semua dari kita mengerti tentang fungsi dari behavior nya.

Bagi kita yang sering memakai react harusnya tidak asing lagi dengan namanya useEffect ini. Tetapi tidak semua dari kita mengerti tentang fungsi dari behavior nya.

Dulu sebelum kita memakai yang namanya function component, kita pasti sudah terbiasa dengan namanya componentDidMount(), componentDidUpdate(), dan componentWillUnmount(). Tetapi dengan function component, kita hanya akan di berikan 1 fungsi untuk melakukan 3 hal itu dengan yang namanya useEffect.

useEffect akan selalu di panggil pada render yang pertama, dan itu akan berlaku pada jenis effect apapun.

Hati-hati

Perhatikan hal ini baik-baik, penulisan dari useEffect itu sangat sederhana hanya dengan kode seperti berikut:

useEffect(() => (
    console.log('Always rendered.')
))

Namun dia akan selalu di panggil pada saat terjadinya re-render. Jadi apapun yang sifatnya re-render, maka fungsi di atas akan terus muncul. Perhatikan komponen dibawah ini:

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

function App(props) {
    const [name, setName] = useState('');
    useEffect(() => console.log('Always rendered.'));

    return <input type='text' value={name} onChange={(e) => setName(e.target.value)} />;
}

Harusnya, setiap kita ketik di dalam text input itu, maka bacaan Alwayas rendered. akan muncul terus pada console dev tools kita. Jadi pastikan kebutuhan Anda benar-benar ada disini, karena jika tidak, ini bisa menyebabkan yang namanya crash atau memory leak.

componentDidMount

Ini adalah fungsi yang kita pakai pada saat memakai react dengan class, apa yang dilakukan fungsi ini adalah dia akan dirender pada render pertama saja. Dengan useEffect, kita bisa dengan mudah hanya menambahkan [] pada parameter setelah callback.

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

function App(props) {
    const [name, setName] = useState('');
    useEffect(() => console.log('Always rendered.'), []);

    return <input type='text' value={name} onChange={(e) => setName(e.target.value)} />;
}

Perhatikan pada bagian useEffect(() => console.log('...'), []);, ... akan di panggil pada render yang pertama saja, kita sekarang Anda ketik apapun di dalam text input itu. Maka ... tidak akan di panggil lagi.

componentDidUpdate

Fungsi ini akan kita panggil jika kita ingin re-render komponen yang bergantu dengan props. Kurang lebih penulisannya seperti ini:

componentDidUpdate(someProps) {
    console.log('Will render if someProps changed.')   
}

Perhatikan baik-baik, fungsi ini akan di panggil jika ada perubahan yang terjadi pada prevProps. Dengan useEffect, kita dapat dengan mudah melakukannya seperti:

useEffect(() => {
    console.log('Will render if someProps changed..')
}, [someProps]);

Perhatikan contoh dibawah ini:

function App(props) {
    const [online, setOnline] = useState(false);
    useEffect(() => {
        console.log(`I now ${online ? 'online' : 'offline'}`);
    }, [online]);

    return <button onClick={(e) => setOnline(!online)}>Hit</button>;
}

Tulisan antara online dan offline akan terpacu jika kita tekan tombol tersebut. Jadi seandainya [online] kita hilangkan dari useEffect tersebut, dia tidak akan muncul ketika kita pacu tombol hit itu.

componentWillUnmount

Ini adalah fungsi dimana kita ingin membersihkan sesuatu setelah terjadinya render. Sulit memang menjelaskan tentang hal ini, namun saya akan coba membuat Anda mengerti. Saya akan membuat contoh tentang event ketika browser di scroll ke bawah dan ke atas.

function App(props) {
    const [scrollPosition, setScrollPosition] = useState(window.scroll);

    function updateScrollPosition() {
        console.log(window.scrollY);
        setScrollPosition(window.scrollY);
    }

    useEffect(() => {
        window.addEventListener('scroll', updateScrollPosition);
    });

    return <div style={{ height: '3000px' }} />;
}

Untuk contoh ini, saya akan memakai Chrome dari pada firefox. Saya buat height pada div tersebut 3000px agar kita bisa scroll ke atas dan bawah. Ketika kita buka console pada devtools nya, kita akan melihat posisi setiap kita melakukan scroll.

Devtools

Dan sekarang jika kita buat pada devtools tersebut getEventListeners(window), kita akan mendapatkan hasil kurang lebih seperti ini:

Devtools with getEventListeners

Perhatikan, kita akan mendapatkan nilai 12 pada array tersebut. Dan ketika kita scroll lagi atas bawah itu akan terus bertambah.

Always increased

Nah oleh karena itulah, disini kita butuh yang namanya cleanup. Setelah aksi pertama dilakukan maka akan di bersihkan jika ingin melakukan aksi selanjutnya. Jadi kita bisa tambahkan itu dengan cara seperti:

useEffect(() => {
    window.addEventListener('scroll', updateScrollPosition);

    return () => window.removeEventListener('scroll', updateScrollPosition)
});

Setelah itu, harusnya sekarang jika kita lihat kembali di devtools console akan mulai dari 0 lagi.

Cleanup

Jangan tertipu

Ada masalah yang harus Anda ketahui sewaktu listener ini berlangsung. Coba lihat contoh dibawah ini:

useEffect(() => {
    console.log('Attaching');
    window.addEventListener('scroll', updateScrollPosition);

    return () => {
        console.log('Detaching');
        window.removeEventListener('scroll', updateScrollPosition)
    }
});

Anda akan melihat behind the scene sewaktu scroll kita lakukan. Yang itu sebenarnya bisa menyebabkan yang namanya leak memory. Perhatikan gambar dibawah ini untuk proses nya.

Attach and Detach

Untuk problem seperti ini lah kita butuh yang namanya deps: [] di useEffect tersebut. Hapus fungsi remove listener nya dan tambahkan [] pada effect nya seperti:

useEffect(() => {
    window.addEventListener('scroll', updateScrollPosition);
}, []);

Maka sekarang, jika kita buat getEventListeners(window) pada devtools nya, semua akan bersih. Karena pada dasarnya, useEffect tersebut akan di panggil hanya dirender pertama saja. Mudah-mudahan dengan penjelasan di atas Anda akan mengerti tentang bagaimana sebenarnya useEffect itu bekerja.

Jika Anda tertarik dengan pelajaran seperti ini, saya juga sudah membuat tutorial nya tentang React di youtube yang itu bisa Anda lihat di video ini

Share artikel ini ke teman-teman Anda agar mereka juga mengetahui tentang bagaiman sebenarnya behind the scenes dari useEffect ini. Saya Irsyad, saya akan melihat Anda di artikel selanjutnya.

Karteil
Destinasi Utama Belajar Online dengan Format Tulisan yang Elegan
Kunjungi Sekarang