v2.5.2
Giriş yap

React useEffect cleanup nedir?

howlberg
806 defa görüntülendi

useEffect fonksiyonunda neden cleanup'a ihtiyaç duyarız? Component unmount olduğunda mı calısır? İnternette araştırdım ama bir türlü kafamdaki soruları çözemedim.

Cevap yaz
Cevaplar (2)
ebykdrms
601 gün önce

Evet, component unmount olduğunda çalışır. Aşağıda kaynağını verdiğim sitede olay şu şekilde açıklanmış:

React useEffect cleanup: Nasıl ve ne zaman kullanılır?

useEffect(()=>{
   // effect
   return () => {
       // cleanup
   }
},[input]);

Hiç şu hatayla karşılaştınız mı?
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

Mesaj, bir component unmount olup kullanılmaz hale geldikten sonra component'te bişeyler değiştirmeye çalıştığımızı söylüyor.
Bunun birçok nedeni olabilir. Ama en yaygın olarak ya bir websocket bağlantısını sonlandırmadan veya asenkron bir fonksiyon henüz sonuç dönmeden önce component'iniz unmount olmuştur.
Peki bunu nasıl çözeriz?

useEffect hook'undaki cleanup fonksiyonu

useEffect fonksiyonunda bir fonksiyon return edersek bileşenden ayrıldığımızda bu fonksiyon çalışır. Bu çok kullanışlıdır çünkü gereksiz işlemlerin yapılması veya bellek sızıntılarını önlenmesi için kullanılabilir.
websocket bağlantısının aboneliğinin iptal edildiği bir örnek:

useEffect(() => {
    API.subscribe()
    return function cleanup() {
        API.unsubscribe()
    }
});
Unmount olmuş bir bileşenin state'ini set etmeyin

Yaygın bir kullanım senaryosunda; asenkron bir fonksiyondan sonuç döndüğünde state güncellenir. Peki asenkron fonkisyon sonuç dönmeden önce component unmount olursa? Biz bu durumu kontrol etmezsek react, component unmount olsa bile state'i güncellemeye çalışır.
Aşağıdaki örnekte bir fetch isteğinden yanıt döndüğünde loading state'ini güncelliyorum.

useEffect(() => {
    fetchAPI.then(() => {
        setLoading(false)
    })
}, [])

Ama fetchAPI'nin then fonksiyonu henüz çalışmadan önce bileşen unmount olabilir ve react yine de loading state'imi güncellemeye çalışır. Bu durumda uygulama patlamasa bile react bize uyarı verir.
Basit bir kontrolle bu sorunun önüne geçebiliriz.

useEffect(() => {
    let mounted = true
    fetchAPI.then(() => {
        if (mounted) {
            setloading(false)
        }
    })

    return function cleanup() { mounted = false }
}, []);
Ekstra: Axios isteğini iptal edin

Axios, bir istek tamamlanmadan önce iptal etme seçeneğine sahiptir. Bu özellik bellek sızıntısının önüne geçmek için cleanup fonksiyonunda kullanışlıdır.

useEffect(() => {
    const source = axios.CancelToken.source()

    const fetchUsers = async () => {
        try {
            await Axios.get('/users', {
                cancelToken: source.token,
            })
            // ...
        } catch (error) {
            if (Axios.isCancel(error)) {
                console.log('Request iptal edildi.', error.message);
            } 
            else { throw error }
        }
    }

    fetchUsers()

    return () => {
        source.cancel()
    }
}, [])

Kaynak: https://dev.to/otamnitram/react-useeffect-cleanup-how-and-when-to-use-it-2hbm

tayfunerbilen
601 gün önce

en basitinen bi sayaç yaptığını düşün, setInterval() ile her 1 saniyede bir değer değiştiriyorsun.
bu sayaç componenti ile işin bittiğinde arkaplanda bu fonksiyon çalışmaya devam etmemesi için, bunu temizlemen gerekiyor.
bu ve bunun gibi örnekler çoğaltılabilir, amaç performansa etki edecek şeylerden kaçınmak için temizlemektir.
bunun içinde useEffect() içinde bir fonksiyon return ederek yapıyorsunuz.