useEffectKait Bereaksi


useEffectHook memungkinkan Anda untuk melakukan efek samping pada komponen Anda .

Beberapa contoh efek samping adalah: mengambil data, memperbarui DOM secara langsung, dan pengatur waktu.

useEffectmenerima dua argumen. Argumen kedua adalah opsional.

useEffect(<function>, <dependency>)


Mari kita gunakan timer sebagai contoh.

Contoh:

Gunakan setTimeout()untuk menghitung 1 detik setelah render awal:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Tapi tunggu!! Saya terus menghitung meskipun seharusnya hanya menghitung sekali!

useEffectberjalan di setiap render. Itu berarti bahwa ketika hitungan berubah, render terjadi, yang kemudian memicu efek lain.

Ini bukan yang kita inginkan. Ada beberapa cara untuk mengontrol kapan efek samping berjalan.

Kita harus selalu menyertakan parameter kedua yang menerima array. Kami secara opsional dapat meneruskan dependensi ke useEffectdalam array ini.

1. Tidak ada ketergantungan yang berlalu:

useEffect(() => {
  //Runs on every render
});

2. Array kosong:

useEffect(() => {
  //Runs only on the first render
}, []);

3. Alat peraga atau nilai negara:

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

Jadi, untuk memperbaiki masalah ini, mari kita jalankan efek ini pada render awal saja.

Contoh:

Hanya jalankan efek pada render awal:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- add empty brackets here

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Contoh:

Berikut adalah contoh useEffectHook yang bergantung pada variabel. Jika countvariabel diperbarui, efeknya akan berjalan lagi:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

ReactDOM.render(<Counter />, document.getElementById('root'));

Jika ada banyak dependensi, mereka harus disertakan dalam useEffectlarik dependensi.


w3schools CERTIFIED . 2022

Dapatkan Sertifikasi!

Selesaikan modul React, kerjakan latihannya, ikuti ujiannya, dan dapatkan sertifikasi w3schools!!

$95 DAFTAR

Pembersihan Efek

Beberapa efek memerlukan pembersihan untuk mengurangi kebocoran memori.

Batas waktu, langganan, pendengar acara, dan efek lain yang tidak lagi diperlukan harus dibuang.

Kami melakukan ini dengan memasukkan fungsi pengembalian di akhir useEffectHook.

Contoh:

Bersihkan timer di ujung useEffectHook:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let timer = setTimeout(() => {
    setCount((count) => count + 1);
  }, 1000);

  return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById("root"));

Catatan: Untuk menghapus timer, kami harus menamainya.


Uji Diri Anda Dengan Latihan

Olahraga:

Apa yang perlu Anda tambahkan ke argumen kedua dari useEffectHook untuk membatasinya agar hanya berjalan pada render pertama?

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    setData(getData())
  }, );

  return <DisplayData data={data} />;
}

ReactDOM.render(<App />, document.getElementById('root'));