Memahami Hooks useEffect Pada React
Penggunaan hooks di React semenjak komponen tidak lagi diharuskan melalui class namun dapat juga menggunakan function sebagai komponen (Introducing Hooks). Sebelumnya ketika masih menggunakan komponen class kita dituntut untuk memanipulasi life-cycle dengan method seperti constructor, render, componetDidMount dan sebagainya. Semenjak penggunaan komponen function diperbolehkan tentunya method-method tersebut tidak dapat digunakan. React juga memiliki beberapa hooks lainnya, namun sebelum memahami useEffect, sebaiknya kalian sudah memahami useState terlebih dahulu karena contoh pada artikel ini akan menggunakan hooks tersebut.
Life-Cycle Komponen React
Sampai sini sepertinya kita harus memahami dulu life-cycle sebelum melanjutkan pembahasan. Life-cycle disini dapat diartikan sebagai siklus hidup dari sebuah komponen yang dapat dikelompokkan menjadi mounting, updating, dan unmounting. Mari kita bandingkan antara komponen class dan juga function yang menggunakan hooks.
Mounting
Mounting disini bisa kita sebut sebagai proses pemasangan dimana data disiapkan untuk dilakukan rendering UI. Proses mounting sendiri terdiri dari dua proses yaitu sebelum dan sesudah mounting. Proses sebelum mounting terjadi ketika komponen mulai di build sedangkan setelahnya adalah ketika komponen telah ditampilkan (dipasang ke UI)
Pada contoh dibawah, class komponen menggunakan constructor untuk menyiapkan state awal dari count yaitu bernilai angka 0 dan kemudian di render pada tag HTML h1. Setelah itu pada componentDidMount nilai count dirubah menjadi 1.
import React from 'react';
class MyComponent extends React.Component {
//Sebelum Mounting
constructor(props){
super(props);
this.state = {
count : 0,
}
}
//Setelah Mounting
componentDidMount() {
this.setState({count: 1})
}
render() {
return <h1>Count: {this.state.count}</h1>
}
}
Pada contoh dibawah ini, tujuannya juga sama seperti komponen diatas, dimana sebelum mounting nilai count di set menjadi 0 dan setelah mounting kita menggunakan useEffect menggantikan componentDidMount untuk merubah count menjadi 1
import React, {useState, useEffect} from 'react';
const MyComponent = () => {
//Sebelum Mounting
const [count, setCount] = useState(0);
useEffect(()=>{
//Setelah Mounting
setCount(1)
}, []) return <h1>Count: {this.state.count}</h1>
}
Bisa dilihat diatas, useEffect memiliki dua buah parameter yang pertama adalah sebuah function, yang kedua ada array dependencies. Parameter kedua ini diberikan variabel (biasanya sebuah state) dimana ketika nilai variabel itu berubah useEffect akan dieksekusi (dibahas pada bagian Updating). Kalau dibiarkan kosong, maka useEffect hanya akan dijalankan sekali.
Updating
Updating adalah kondisi ketika komponen telah ditampilkan tetapi ada nilai variabel atau state yang berubah. Biasanya perubahan terjadi karena ada inputan dari pengguna, atau bisa juga hasil fetch dari webservice yang mempengaruhi komponen tersebut.
Mari kita lihat contoh sederhana pada komponen class. Disini kita memodifikasi sedikit komponen sebelumnya. Kita menambahkan state baru yaitu status sebagai string kosong. kemudian kita menambahkan method setCount yang akan menambah satu nilai count ketika button ditekan. Kemudian di method componentDidUpdate kita mengecek jika prevState dari count adalah 0 maka nilai status akan menjadi “nilai berubah”. componentDidUpdate akan selalu melakukan pengecekan ketika komponen mengalami perubahan, karena itu perlu kita bungkus menggunakan pengecekan kondisional agar tidak terjadi error dimana komponen dirender terus menerus tak terbatas (infinite loop)
import React from 'react';class MyCompClass extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
status: ""
};
} setCount() {
this.setState({count: this.state.count + 1});
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count === 0) {
this.setState({status: "nilai berubah"});
}
}
render() {
return (<div>
<h1>Class Count: {this.state.count}</h1>
<p>{this.state.status}</p>
<button onClick={() => this.setCount()}>+</button>
</div>);
}
}
Dibandingkan dengan class komponen penggunaan hooks dan function komponen terlihat lebih sederhana meskipun dengan logika yang serupa. sama seperti sebelumnya, status di set sebagai string kosong, kemudian setiap count mengalami perubahan maka status diset menjadi “nilai berubah”.
import React from 'react';
const MyCompHooks = () => {
const [count, setCount] = React.useState(0);
const [status, setStatus] = React.useState("");
React.useEffect(() => {
if (count !== 0) {
setStatus("nilai berubah");
}
}, [count]);
return (
<div>
<h1>Hooks Count: {count}</h1>
<p>{status}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
Sekarang jika dilihat, array pada useEffect kita berikan variabel count. Arti dari hal tersebut adalah count merupakan dependensi dari useEffect tersebut, atau variabel count akan selalu diperhatikan. Jika ada perubahan maka useEffect akan mengupdate komponennya.
Unmounting
Mounting adalah pemasangan komponen maka unmounting adalah pembongkaran atau pelepasan suatu komponen. Unmounting sering digunakan ketika merubah UI namun ada aksi yang perlu dijalankan. Misalnya ketika proses logout berlangsung, sebelum halaman ditutup kita ingin menghapus informasi pengguna terlebih dahulu.
Disini kita memiliki sebuah komponen utama App yang dapat mengganti antara dua komponen. Pada komponen class, kita menambahkan method componentWillUnmount dengan pesan “class unmount”. Sedangkan pada komponen hooks kita menambahkan sebuah hooks useEffect lagi (bisa lebih dari satu) karena dia tidak memiliki dependensi dengan variabel lain.
import React from "react";
import "./styles.css";export default function App() {
const [toggle, setToggle] = React.useState(true);
return (
<div className="App">
<button onClick={() => setToggle(!toggle)}>
Toggle component
</button>{toggle ? <MyCompHooks /> : <MyCompClass />}
</div>
);
}class MyCompClass extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
status: ""
};
}
setCount() {
this.setState({
count: this.state.count + 1
});
}
componentDidUpdate(_, prevState) {
if (prevState.count === 0) {
this.setState({
status: "nilai berubah"
});
}
}
componentWillUnmount() {
console.log("class unmount");
}
render() {
return (
<div>
<h1>Class Count: {this.state.count}</h1>
<p>{this.state.status}</p>
<button onClick={() => this.setCount()}>+</button>
</div>
);
}
}const MyCompHooks = () => {
const [count, setCount] = React.useState(0);
const [status, setStatus] = React.useState("");
React.useEffect(() => {
if (count !== 0) {
setStatus("nilai berubah");
}
}, [count]);
React.useEffect(() => {
return () => {
console.log("hooks unmount");
};
}, []);
return (
<div>
<h1>Hooks Count: {count}</h1>
<p>{status}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
componentWillUnmount disini digantikan dengan sebuah return function pada use effect yang akan dieksekusi hanya ketika komponen dibongkar atau dilepas dari UI.
Kesimpulan
Dari contoh-contoh diatas, bisa dilihat tujuan dari penggunaan useEffect adalah untuk menggantikan beberapa metode manipulasi life-cycle yang sebelumnya ada pada komponen class. Namun penggunaan useEffect tidak hanya sebatas contoh yang diberikan saja. Pembuatan custom hooks atau modifikasi dari hooks juga dapat dilakukan menggunakan useEffect. Selain itu juga terlihat jelas menggunakan function komponen dengan hooks baris kode menjadi lebih ramping dibandingkan dengan menggunakan class komponen dan metode-metodenya.
Mungkin itu saja dari saya. Sebelumnya saya ingin meminta maaf karena sangat banyak kekurangan pada tulisan ini. Semoga kita bisa terus berbagi ilmu agar sukses bersama-sama.