Takip et

React Native Navigasyon Yaşam Döngüsünü Anlamak: Kapsamlı Bir Rehber

React Native uygulamanızda navigasyonun nasıl çalıştığını, ekranlar arası geçişlerin yaşam döngüsünü ve performans üzerindeki etkilerini merak ediyor musunuz? Bu rehber, React Navigation’ın derinliklerine inerek uygulamanızın daha verimli çalışmasını sağlayacak ipuçları sunuyor.

Modern mobil uygulamaların olmazsa olmazı, kullanıcıların ekranlar arasında sorunsuz ve sezgisel bir şekilde gezinmesini sağlayan güçlü bir navigasyon sistemidir. React Native ile uygulama geliştirirken, kullanıcı deneyiminin (UX) temelini oluşturan bu navigasyon mekanizmasının nasıl çalıştığını anlamak kritik bir öneme sahiptir. Peki, bir ekranın ne zaman yüklendiği (mount), ne zaman odaklandığı (focus), ne zaman odağını kaybettiği (blur) veya ne zaman kaldırıldığı (unmount) gibi yaşam döngüsü olayları uygulamanızın performansı, bellek tüketimi ve genel kullanıcı akışı üzerinde ne gibi etkilere sahiptir? Bu soruların cevapları, daha optimize ve hatasız uygulamalar geliştirmenizin anahtarıdır.

React Navigation, React Native ekosistemindeki en popüler ve güçlü navigasyon kütüphanesidir. Ancak, sunduğu esneklik ve zengin özellikler beraberinde karmaşıklık da getirebilir. Uygulamanızın her bir ekranının yaşam döngüsü boyunca hangi olayları tetiklediğini bilmek, gereksiz yeniden render işlemlerini önlemek, bellek sızıntılarını tespit etmek ve kullanıcıya daha akıcı bir deneyim sunmak için hayati öneme sahiptir. Örneğin, bir profil sayfasının her odaklandığında güncel verileri çekmesi gerektiğinde, bu işlemi doğru yaşam döngüsü olayına bağlamak, hem performansı artırır hem de kullanıcıya her zaman en yeni bilgiyi sunar. Aksi takdirde, verilerin eski kalması veya gereksiz yere birden çok kez çekilmesi gibi sorunlarla karşılaşabilirsiniz.

Bu makale boyunca, React Navigation’ın temelden ileri seviyeye kadar tüm yaşam döngüsü mekanizmalarını derinlemesine inceleyeceğiz. Ekranların mount, unmount, focus ve blur durumlarını nasıl yönettiğimizi, farklı navigatör tiplerinin (Stack, Tab, Drawer) bu durumlara nasıl etki ettiğini ve performans optimizasyonu için hangi teknikleri kullanabileceğimizi örneklerle açıklayacağız. Ayrıca, gerçek dünya senaryolarında karşılaşabileceğiniz sorunlara çözüm bulmanızı sağlayacak vaka analizleri ve ipuçları da sunacağız. Hazırsanız, React Native navigasyonunun gizemli dünyasına bir yolculuğa çıkalım!

Temel Kavramlar: React Native Navigasyonunu Tanıyalım

React Native navigasyon dünyasına adım atmadan önce, temel kavramları sağlam bir zemine oturtmak oldukça önemlidir. React Navigation, uygulamanızın ekranlar arası geçişlerini yönetmek için bir dizi bileşen ve API sunar. Temelde, her bir ekran (Screen), bir navigatör (Navigator) içinde tanımlanır ve bu navigatörler, uygulamanızın gezinme hiyerarşisini oluşturur. Bu hiyerarşi, kullanıcıların bir ekrandan diğerine nasıl geçiş yaptığını, geri dönüş mekanizmalarını ve ekranların nasıl yığıldığını veya kaldırıldığını belirler.

React Navigation’daki en yaygın navigatör tipleri şunlardır:

  • Stack Navigator: Adından da anlaşılacağı gibi, ekranları bir “yığın” (stack) yapısında yönetir. Yeni bir ekran açtığınızda, mevcut ekranın üzerine itilir ve geri düğmesine bastığınızda üstteki ekran yığından kaldırılır. Bu, web tarayıcılarının geçmiş yönetimine benzer bir model sunar.
  • Tab Navigator: Genellikle uygulamanın alt kısmında veya üst kısmında görünen sekmeler aracılığıyla farklı ana bölümlere hızlı erişim sağlar. Her sekme, kendi içinde ayrı bir navigasyon yığınına sahip olabilir.
  • Drawer Navigator: Genellikle ekranın solundan veya sağından kayarak açılan bir menü şeklinde çalışır ve genellikle uygulamanın ana bölümlerine erişim sağlar.

Şimdi, “yaşam döngüsü” kavramına gelelim. Bir React Native ekranının yaşam döngüsü, ilgili ekranın bir navigasyon yığınına eklenmesinden (mount), kullanıcı tarafından görünür hale gelmesine (focus), başka bir ekrana geçiş yaparak arka plana düşmesine (blur) ve en sonunda tamamen bellekten kaldırılmasına (unmount) kadar geçen süreci ifade eder. Bu olayları doğru anlamak, uygulamanızın kaynaklarını verimli kullanmak ve kullanıcıya kesintisiz bir deneyim sunmak için kritik öneme sahiptir.

Örneğin, bir ekranın mount edilmesi, o ekranın bileşenlerinin ilk kez oluşturulduğu ve DOM’a eklendiği anlamına gelir. unmount ise, ekranın DOM’dan kaldırıldığı ve kaynaklarının serbest bırakıldığı durumdur. focus olayı, kullanıcının o anda etkileşimde olduğu ekranı, blur olayı ise arka plana düşen veya odağını kaybeden ekranı temsil eder. Bu durumlar, özellikle veri çekme, animasyon başlatma veya bellek tüketen işlemler yaparken doğru zamanda müdahale etmenizi sağlar. İleriye dönük olarak, bu yaşam döngüsü olaylarını React hook’ları ile nasıl yöneteceğimizi daha detaylı inceleyeceğiz.

Ekran Yaşam Döngüsü Olayları: useFocusEffect ve Diğer Hook’lar Nasıl Çalışır?

React Navigation’da bir ekranın yaşam döngüsünü anlamak ve yönetmek, uygulamanızın hem performansı hem de veri tutarlılığı açısından hayati öneme sahiptir. Bu bağlamda, useFocusEffect hook’u ve standart React hook’ları (özellikle useEffect) arasındaki farkları kavramak büyük fayda sağlayacaktır. Bir ekranın temel yaşam döngüsü olayları şunlardır:

  • Mount: Ekran bileşeninin ilk kez oluşturulması ve navigasyon ağacına eklenmesi. Bu genellikle bir ekran ilk kez açıldığında veya navigatör bileşeni ilk render edildiğinde gerçekleşir.
  • Unmount: Ekran bileşeninin navigasyon ağacından kaldırılması ve bellekten serbest bırakılması. Bu, genellikle bir yığından (stack) bir ekranı geri çektiğinizde veya bir tab navigatöründe tamamen farklı bir sekmeye geçiş yapıp eski sekmenin bileşenlerinin kaldırılmasına izin verildiğinde meydana gelir.
  • Focus: Ekranın kullanıcı tarafından görünür ve etkileşimde olunur hale gelmesi. Bir yığındaki en üstteki ekran veya o anda seçili olan tab ekranı odaklanmış durumdadır.
  • Blur: Ekranın odağını kaybetmesi ve arka plana geçmesi. Başka bir ekrana geçtiğinizde veya bir modal açıldığında, mevcut ekran “blur” durumuna geçer.

Peki, bu olayları React bileşenlerimizde nasıl yakalarız? Standart React’in useEffect hook’u mount ve unmount durumlarını yönetmek için harikadır. Örneğin, bir API çağrısını ekran yüklendiğinde yapmak veya bir aboneliği temizlemek için useEffect kullanabilirsiniz:


import React, { useEffect } from 'react';
import { View, Text } from 'react-native';

function ProfileScreen() {
  useEffect(() => {
    console.log('ProfileScreen yüklendi (mounted)');
    // API çağrısı yap, abonelik başlat
    return () => {
      console.log('ProfileScreen kaldırıldı (unmounted)');
      // Aboneliği temizle, kaynakları serbest bırak
    };
  }, []); // Boş bağımlılık dizisi ile sadece mount ve unmount'ta çalışır

  return (
    
      Profil Sayfası
    
  );
}

Ancak, useEffect tek başına focus ve blur olaylarını doğrudan izlemez. Bir ekran, bir Stack Navigator'da başka bir ekranın altına itildiğinde veya bir Tab Navigator'da farklı bir sekmeye geçildiğinde unmount olmayabilir; sadece odağını kaybeder (blur). İşte bu noktada @react-navigation/native paketinden gelen useFocusEffect hook'u devreye girer. useFocusEffect, bir ekran odaklandığında (focus) çalışan bir etki (effect) kaydetmenizi sağlar ve ekran odağını kaybettiğinde (blur) veya bileşen kaldırıldığında temizleme (cleanup) işlevi döndürebilirsiniz.


import React, { useCallback } from 'react';
import { View, Text } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';

function HomeScreen() {
  useFocusEffect(
    useCallback(() => {
      console.log('HomeScreen odaklandı (focused)');
      // Ekran her odaklandığında yapılacak işlemler (veri çekme gibi)
      return () => {
        console.log('HomeScreen odağını kaybetti (blurred)');
        // Ekran odağını kaybettiğinde temizleme işlemleri
      };
    }, []) // Bağımlılık dizisi boş bırakılırsa her odaklanmada çalışır
  );

  return (
    
      Ana Sayfa
    
  );
}

Burada useCallback kullanmamız önemlidir, çünkü useFocusEffect fonksiyonunun her render'da yeniden oluşturulmasını engeller, böylece gereksiz yeniden çalıştırmaların önüne geçeriz. useFocusEffect sayesinde, bir kullanıcının belirli bir ekrana her döndüğünde güncel verileri otomatik olarak yüklemesini sağlayabilir veya o ekrana özel animasyonları başlatıp durdurabilirsiniz. Bu, özellikle performans açısından kritik olan veya her zaman en güncel veriyi göstermesi gereken ekranlar için vazgeçilmez bir araçtır.

Uzman İpucu: useFocusEffect içinde gerçekleştirdiğiniz abonelikleri veya zamanlayıcıları, cleanup fonksiyonunda mutlaka temizleyin. Aksi takdirde, bellek sızıntıları yaşayabilir ve uygulamanızın kararlılığını bozabilirsiniz. Örneğin, setTimeout veya setInterval kullandığınızda, clearTimeout veya clearInterval ile temizlemeyi unutmayın.

Farklı Navigatör Tiplerinin Yaşam Döngüsüne Etkisi Nedir? (Stack, Tab, Drawer)

React Navigation, farklı kullanıcı arayüzü desenlerine uygun olarak Stack, Tab ve Drawer gibi çeşitli navigatör tipleri sunar. Her bir navigatörün, içerdiği ekranların yaşam döngüsünü farklı şekillerde yönetmesi, geliştiricilerin dikkat etmesi gereken önemli bir detaydır. Bu farklılıklar, uygulamanızın performansını ve bellek kullanımını doğrudan etkileyebilir.

Stack Navigator'ın Yaşam Döngüsü Yaklaşımı

Stack Navigator, mobil uygulamalarda en sık kullanılan navigasyon desenidir. Yeni bir ekran açtığınızda, mevcut ekranın üzerine itilir ve bir "yığın" oluşturulur. Bu yığın yapısı, ekranların yaşam döngüsü üzerinde belirgin bir etkiye sahiptir:

  • Mount/Unmount: Stack Navigator'da bir ekran genellikle yalnızca ilk kez görüntülendiğinde "mount" olur. Bir yığının üzerine yeni bir ekran itildiğinde (navigation.navigate() veya navigation.push()), mevcut ekran "unmount" olmaz, sadece "blur" olur. Bu, kullanıcının geri düğmesine basarak önceki ekrana döndüğünde ekranın daha hızlı görünmesini sağlar çünkü bileşenler zaten bellekte kalmıştır. Bir ekranın gerçekten "unmount" olması için, yığından tamamen çıkarılması gerekir (örneğin, navigation.pop() ile).
  • Focus/Blur: Stack Navigator'da, yığının en üstündeki ekran her zaman "focused" durumdadır. Yeni bir ekran itildiğinde, mevcut ekran "blur" olur ve yeni ekran "focus" olur. Geri gelindiğinde ise, eski ekran tekrar "focus" olur. Bu davranış, useFocusEffect hook'unu kullanarak odaklanma anında veri çekme veya animasyon başlatma gibi işlemler için idealdir.

Bu yaklaşım, hızlı geçişler için harika olsa da, eğer yığında çok fazla ve bellek yoğun ekran varsa, uygulamanızın bellek tüketimi artabilir. Bu nedenle, yığındaki ekranların ne zaman gerçekten serbest bırakılması gerektiğini düşünmek önemlidir.

Tab Navigator'ın Yaşam Döngüsü Yaklaşımı

Tab Navigator, farklı ana bölümlere hızlı erişim sağlayan sekmeler sunar. Tab Navigator'ın ekran yaşam döngüsü üzerindeki etkisi, Stack Navigator'dan biraz farklıdır ve yapılandırmaya bağlı olarak değişebilir:

  • Lazy Loading: Varsayılan olarak, Tab Navigator'daki sekmeler genellikle "tembel yükleme" (lazy loading) ile çalışır. Yani, bir sekme yalnızca ilk kez seçildiğinde "mount" olur. Bu, uygulamanın başlangıç performansını artırır çünkü tüm sekmeler aynı anda yüklenmez.
  • Unmount Davranışı: Bir sekmeye geçiş yaptığınızda, önceki sekmenin içindeki ekranlar genellikle "unmount" olmaz, sadece "blur" olur. Bu, kullanıcının sekmeler arasında hızlıca geçiş yapabilmesini sağlar. Ancak, bazı durumlarda (örneğin, belirli bir sekmeden çok uzaklaşıldığında) Tab Navigator, performans amacıyla bazı sekmeleri unmount etmeye karar verebilir. Bu davranışı unmountOnBlur prop'u ile kontrol edebilirsiniz. Eğer unmountOnBlur değeri true olarak ayarlanırsa, bir sekme odağını kaybettiğinde içindeki bileşenler unmount edilir ve bir sonraki odaklanmada tekrar mount edilir.


  {/* Sekmeleriniz */}

Bu, bellek tüketimini azaltmak için faydalı olabilir, ancak sekme geçişlerinde hafif bir gecikmeye neden olabilir.

Drawer Navigator'ın Yaşam Döngüsü Yaklaşımı

Drawer Navigator, genellikle uygulamanın ana bölümlerine erişim sağlayan bir yan menüdür. Yaşam döngüsü açısından Stack ve Tab Navigator arasında bir denge sunar:

  • Lazy Loading/Unmount: Drawer Navigator da genellikle tembel yükleme yapar; yani, bir menü öğesi seçilene kadar ilgili ekran mount edilmez. Stack Navigator gibi, bir menü öğesi seçildiğinde, genellikle önceki ekran unmount olmaz, sadece blur olur. Ancak, Drawer Navigator içindeki her menü öğesi kendi içinde bir Stack Navigator barındırdığında, bu iç stack'lerin yaşam döngüsü kuralları geçerli olur.

Özetle, her navigatör tipi ekran yaşam döngüsünü farklı şekillerde yönetir. Performans ve bellek yönetimi için, uygulamanızın ihtiyaçlarına en uygun navigatör tipini seçmeli ve yaşam döngüsü olaylarını dikkatlice takip etmelisiniz. Özellikle bellek sızıntılarını önlemek ve gereksiz render işlemlerini minimize etmek için bu farklılıkları iyi anlamak kritik öneme sahiptir.

Performans Optimizasyonu: Navigasyon Yaşam Döngüsü ile Bellek Yönetimi Nasıl Yapılır?

React Native uygulamalarında performans, kullanıcı deneyiminin temel taşlarından biridir. Özellikle navigasyon sırasında yaşanan yavaşlıklar veya takılmalar, kullanıcıları hızla uygulamadan soğutabilir. Navigasyon yaşam döngüsünü doğru bir şekilde yönetmek, bellek optimizasyonu ve genel performans artışı için kritik bir role sahiptir. Peki, bu optimizasyonu nasıl sağlarız?

Öncelikle, React'in temel optimizasyon prensiplerini navigasyon bağlamında ele almalıyız. Gereksiz yeniden render işlemleri, uygulamanın performansını ciddi şekilde düşürebilir. Bir ekranın odağını kaybetmesi (blur olması) veya navigasyon yığınında başka bir ekranın altına itilmesi durumunda bile, React genellikle bu ekranı bellekte tutar. Eğer bu ekranda karmaşık hesaplamalar, büyük veri kümeleri veya yoğun DOM manipülasyonları varsa ve bu ekranlar sürekli yeniden render oluyorsa, performans sorunları kaçınılmaz hale gelir.

İşte navigasyon yaşam döngüsü ile performans optimizasyonu için bazı stratejiler:

1. React.memo ve useCallback/useMemo Kullanımı

Bileşenlerinizin gereksiz yere yeniden render olmasını engellemek için React'in memoizasyon özelliklerinden faydalanın. React.memo, bir bileşenin prop'ları değişmediği sürece yeniden render olmasını engeller. Karmaşık alt bileşenleriniz için bunu kullanmak, navigasyon sırasında performans kazanımı sağlayabilir.


import React, { memo } from 'react';
import { View, Text } from 'react-native';

const MemoizedHeavyComponent = memo(({ data }) => {
  // Sadece 'data' değiştiğinde yeniden render olur
  console.log('Heavy Component Rendered');
  return {data.length} elemanlı veri gösteriliyor;
});

function ParentScreen({ navigation }) {
  const largeData = Array(1000).fill('item'); // Büyük bir veri seti

  // Eğer ParentScreen yeniden render olursa, MemoizedHeavyComponent de render olabilir.
  // Ancak eğer prop'ları (burada largeData) değişmezse, MemoizedHeavyComponent render olmaz.

  return (
    
      Parent Ekranı
      
      

useCallback ve useMemo ise fonksiyon ve değerlerin memoizasyonunu sağlar. Özellikle alt bileşenlere prop olarak fonksiyonlar veya objeler geçiyorsanız, bu hook'ları kullanarak referansların gereksiz yere değişmesini engelleyebilir ve React.memo'nun daha verimli çalışmasını sağlayabilirsiniz.


import React, { useCallback, useMemo, memo } from 'react';
// ... diğer import'lar ...

const MemoizedButton = memo(({ onPressHandler }) => {
  console.log('Button Rendered');
  return 

2. Lazy Loading (Tembel Yükleme)

Bazı navigatörler (örneğin Tab Navigator), varsayılan olarak tembel yükleme yapma yeteneğine sahiptir. Bu, bir sekmenin yalnızca kullanıcı ilk kez o sekmeye geçtiğinde yüklenmesi anlamına gelir. Stack Navigator için de kendi lazy loading mekanizmalarınızı uygulayabilirsiniz, örneğin, belirli bir ekranın yoğun bileşenlerini yalnızca ekrana odaklanıldığında yükleyerek.


// Tab Navigator için varsayılan tembel yükleme

  
   {/* SettingsScreen sadece ilk kez seçildiğinde yüklenir */}

3. unmountOnBlur Kullanımı (Tab Navigator için)

Eğer bir Tab Navigator kullanıyorsanız ve her sekmenin bellek kullanımını minimumda tutmak istiyorsanız, unmountOnBlur prop'unu true olarak ayarlayabilirsiniz. Bu, bir sekme odağını kaybettiğinde içindeki bileşenlerin tamamen unmount edilmesini ve bir sonraki odaklanmada yeniden mount edilmesini sağlar. Bu, daha yavaş geçişlere neden olabilir ancak bellek sızıntılarını ve gereksiz bellek tüketimini büyük ölçüde azaltır.

4. useFocusEffect ile Kaynakları Temizleme

Daha önce bahsettiğimiz gibi, useFocusEffect sadece odaklanma anında kod çalıştırmak için değil, aynı zamanda ekran odağını kaybettiğinde kaynakları temizlemek için de kritik öneme sahiptir. Abonelikleri iptal etmek, zamanlayıcıları temizlemek veya bellek yoğun objeleri serbest bırakmak gibi işlemler, useFocusEffect'in cleanup fonksiyonu içinde yapılmalıdır. Bu, özellikle karmaşık animasyonlar, stream abonelikleri veya büyük veri objeleri kullanan ekranlar için bellek sızıntılarını önlemenin en etkili yoludur.

Uzman İpucu: Navigasyon ağacınızda çok sayıda ekran varsa ve hepsi bellekte tutuluyorsa, uygulamanızın bellek kullanımını izlemek için React Native Debugger veya Flipper gibi araçları kullanın. Bu araçlar, bellek sızıntılarını ve gereksiz yeniden render işlemlerini tespit etmenize yardımcı olacaktır.

Bu stratejileri bir araya getirerek, React Native uygulamanızın navigasyon deneyimini önemli ölçüde iyileştirebilir, bellek kullanımını optimize edebilir ve kullanıcılara daha akıcı ve tepkisel bir arayüz sunabilirsiniz.

Vaka Analizi: Karmaşık Bir Senaryoda Navigasyon Sorunlarını Çözmek

Gerçek dünya uygulamalarında navigasyon, genellikle basit push ve pop işlemlerinden çok daha karmaşıktır. Bu vaka analizinde, bir sosyal medya uygulamasında sıkça karşılaşılan bir senaryoyu ele alacak ve navigasyon yaşam döngüsü bilgilerimizi kullanarak olası sorunları nasıl çözebileceğimizi göstereceğiz.

Senaryo: Dinamik Profil Sayfası ve Haber Akışı Entegrasyonu

Bir sosyal medya uygulamanız olduğunu varsayalım. Uygulamanın ana ekranında (FeedScreen) bir haber akışı var. Bu akıştaki her gönderi, gönderiyi paylaşan kullanıcının profil fotoğrafına tıklanarak kullanıcının profil sayfasına (ProfileScreen) gitmenizi sağlıyor. Ancak bu profil sayfası, aşağıdaki gibi dinamik özelliklere sahip:

  1. Profil sayfası, her ziyaret edildiğinde kullanıcının en güncel gönderilerini ve bilgilerini bir API'den çekmeli.
  2. Profil sayfasında, kullanıcının arkadaşları listesini gösteren bir sekme (Tab Navigator içinde) bulunuyor. Bu sekme, yalnızca ilk kez tıklandığında arkadaş listesini çekmeli ve daha sonra aynı sekme tekrar ziyaret edildiğinde yeniden çekmemeli (performans için).
  3. Kullanıcı profil sayfasından başka bir sayfaya (örneğin, bir arkadaşının profiline) navigasyon yaptığında, ana profil sayfasındaki belirli bir zamanlayıcının durdurulması gerekiyor.

Bu senaryoda karşılaşılabilecek potansiyel sorunlar şunlar olabilir:

  • Profil sayfasına her döndüğümüzde verinin eski kalması veya hiç güncellenmemesi.
  • Profil sayfasının her odaklandığında gereksiz API çağrıları yapması, performansı düşürmesi.
  • Arkadaşlar listesi sekmesinin her açılışta veriyi yeniden çekmesi veya hiç çekmemesi.
  • Zamanlayıcının arka planda çalışmaya devam ederek bellek sızıntılarına veya beklenmedik davranışlara neden olması.

Çözüm Yaklaşımı ve Uygulama

Bu sorunları çözmek için React Navigation'ın yaşam döngüsü hook'larını ve React'in temel optimizasyonlarını birleştireceğiz.

1. Güncel Profil Verilerini Her Odaklanmada Çekme (useFocusEffect)

Profil sayfasının her odaklandığında güncel veriyi çekmesini sağlamak için useFocusEffect kullanacağız. Bu, kullanıcının ana akıştan veya başka bir profilden kendi profiline döndüğünde her zaman en yeni bilgiyi görmesini garanti eder.


import React, { useState, useEffect, useCallback } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
import axios from 'axios'; // API çağrısı için

function ProfileScreen({ route, navigation }) {
  const { userId } = route.params;
  const [profileData, setProfileData] = useState(null);
  const [loading, setLoading] = useState(true);

  // Profil verilerini çeken fonksiyon
  const fetchProfileData = async () => {
    setLoading(true);
    try {
      const response = await axios.get(https://api.myapp.com/users/${userId});
      setProfileData(response.data);
    } catch (error) {
      console.error("Profil verisi çekilemedi:", error);
    } finally {
      setLoading(false);
    }
  };

  // Ekran her odaklandığında profil verisini çek
  useFocusEffect(
    useCallback(() => {
      fetchProfileData();
      console.log(Profil Ekranı (ID: ${userId}) odaklandı. Veri yenileniyor.);

      // Zamanlayıcıyı başlat
      const timer = setInterval(() => {
        console.log("Profil Ekranı aktif, zamanlayıcı çalışıyor...");
      }, 5000);

      return () => {
        console.log(Profil Ekranı (ID: ${userId}) odağını kaybetti. Zamanlayıcı durduruluyor.);
        clearInterval(timer); // Ekran odağını kaybettiğinde zamanlayıcıyı durdur
      };
    }, [userId]) // userId değişirse effect yeniden çalışır
  );

  if (loading) {
    return ;
  }

  return (
    
      {profileData?.name}
      {profileData?.bio}
      {/* Diğer profil bileşenleri */}
    
  );
}

2. Arkadaş Listesi Sekmesini Tembel Yükleme (Tab.Screen ve unmountOnBlur)

Arkadaşlar listesi sekmesinin sadece ilk kez tıklandığında yüklenmesini ve performans için her tekrar ziyaret edildiğinde yeniden çekilmemesini istiyoruz. Burada Tab Navigator'ın varsayılan tembel yükleme özelliği ve useEffect'in doğru kullanımı işimize yarayacak. Eğer bellekten tamamen temizlenmesini istersek, unmountOnBlur kullanabiliriz.


// ProfileScreen içindeki Tab Navigator
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const Tab = createMaterialTopTabNavigator();

function ProfileTabs({ userId }) {
  return (
    
      
        {props => }
      
      
        {props => }
      
    
  );
}

// FriendsListScreen bileşeni
function FriendsListScreen({ userId }) {
  const [friends, setFriends] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Bu kod sadece bileşen mount edildiğinde çalışır.
    // Yani, sekme ilk kez seçildiğinde veri çekilir.
    const fetchFriends = async () => {
      setLoading(true);
      try {
        const response = await axios.get(https://api.myapp.com/users/${userId}/friends);
        setFriends(response.data);
      } catch (error) {
        console.error("Arkadaşlar listesi çekilemedi:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchFriends();
    console.log(Arkadaşlar Listesi Ekranı (ID: ${userId}) mount edildi. Veri çekiliyor.);

    return () => {
      console.log(Arkadaşlar Listesi Ekranı (ID: ${userId}) unmount edildi.);
      // Temizleme işlemleri
    };
  }, [userId]); // userId değişirse yeniden yüklenir

  if (loading) {
    return ;
  }

  return (
    
      Arkadaşlar ({friends.length})
      {friends.map(friend => {friend.name})}
    
  );
}

Bu vaka analizinde gördüğümüz gibi, React Navigation'ın yaşam döngüsü hook'larını ve React'in temel hook'larını doğru yerlerde kullanarak, dinamik ve karmaşık navigasyon senaryolarında dahi tutarlı, performanslı ve hatasız uygulamalar geliştirmek mümkündür. useFocusEffect ile dinamik veri yüklemeyi, useEffect ile tek seferlik veri çekmeyi ve cleanup işlemlerini birleştirerek uygulamanızın kontrolünü ele alabilirsiniz.

Sonuç: Öğrendiklerimizi Özetleyelim ve Sıkça Sorulan Sorular

React Native navigasyon yaşam döngüsü, uygulamanızın kalbinde yer alan ve kullanıcı deneyimini doğrudan etkileyen kritik bir konudur. Bu rehber boyunca, React Navigation'ın temelden ileri seviyeye kadar olan mekanizmalarını, ekranların "mount", "unmount", "focus" ve "blur" durumlarını nasıl yönettiğini, farklı navigatör tiplerinin (Stack, Tab, Drawer) bu durumlara nasıl etki ettiğini ve performansı optimize etmek için hangi stratejileri kullanabileceğimizi detaylıca inceledik. Özellikle useFocusEffect gibi özel hook'lar sayesinde, ekran odaklanması ve odağını kaybetme anlarında hassas işlemler gerçekleştirebileceğimizi ve gereksiz bellek tüketimini önleyebileceğimizi gördük.

Unutmayın ki, her bir ekranınızın hangi navigatör içinde bulunduğunu ve bu navigatörün yaşam döngüsünü nasıl yönettiğini anlamak, bellek sızıntılarını engellemek, API çağrılarını doğru zamanda yapmak ve genel uygulama performansını artırmak için elzemdir. React.memo, useCallback, useMemo gibi React optimizasyon araçlarını navigasyonla birleştirmek, özellikle büyük ve karmaşık uygulamalarda gözle görülür iyileşmeler sağlayacaktır. Gerçek dünya vaka analizimizle de, bu teorik bilgileri pratik senaryolara nasıl uygulayabileceğimizi göstermiş olduk.

Artık React Native navigasyon yaşam döngüsüne dair derinlemesine bir anlayışa sahip olduğunuza göre, daha sağlam, hızlı ve kullanıcı dostu mobil uygulamalar geliştirmek için gerekli araçlara sahipsiniz. Bu bilgilerle, uygulamanızın navigasyon akışını daha bilinçli bir şekilde tasarlayabilir ve olası performans sorunlarını proaktif bir yaklaşımla çözebilirsiniz. Geliştirmeye devam edin!

Sıkça Sorulan Sorular

Ekranım neden her geri geldiğimde yeniden render oluyor?
Bir Stack Navigator kullanıyorsanız, önceki ekranınız yeni bir ekran itildiğinde genellikle unmount olmaz, sadece odağını kaybeder (blur). Geri geldiğinizde, zaten bellekte olan bu ekran tekrar odaklanır (focus). Eğer ekranınızdaki veriler veya UI elemanları her odaklanmada güncelleniyorsa ve bu güncellemeler bir state değişimi tetikliyorsa, React doğal olarak bileşeni yeniden render edecektir. Bunu engellemek için React.memo ve useCallback/useMemo kullanarak gereksiz yeniden render işlemlerini azaltabilirsiniz. Ayrıca, useFocusEffect içindeki cleanup fonksiyonunda state'i sıfırlamak da yardımcı olabilir.
İki ekran arasında nasıl veri aktarırım?
React Navigation'da ekranlar arası veri aktarımının birkaç yolu vardır:

  • Route Parametleri: En yaygın yöntemdir. navigation.navigate('ScreenName', { param1: 'value' }) ile veri gönderip, hedef ekranda route.params.param1 ile erişebilirsiniz.
  • Global Durum Yönetimi: Context API, Redux, Zustand gibi kütüphanelerle global bir durum oluşturarak, ekranlar arasında karmaşık veya sık kullanılan verileri paylaşabilirsiniz.
  • Event Emitter: Daha spesifik ve nadir durumlarda, EventEmitter kullanarak ekranlar arasında özel olaylar tetikleyebilir ve dinleyebilirsiniz.
React Navigation'da bellek sızıntılarını nasıl önlerim?
Bellek sızıntılarını önlemek için birkaç temel kurala uymanız önemlidir:

  • Abonelikleri Temizle: useEffect veya useFocusEffect içinde başlattığınız tüm abonelikleri (örneğin WebSocket bağlantıları, event listener'lar) veya zamanlayıcıları (setTimeout, setInterval) mutlaka cleanup fonksiyonunda temizleyin.
  • Referansları Serbest Bırak: Gereksiz yere büyük objeleri state'te veya ref'te tutmaktan kaçının. Ekran unmount olduğunda veya odağını kaybettiğinde, artık ihtiyaç duyulmayan referansları null'a eşitleyerek serbest bırakın.
  • unmountOnBlur Kullanımı: Tab Navigator kullanıyorsanız ve her sekme için bellek tüketimi kritikse, unmountOnBlur prop'unu true olarak ayarlayarak, odağını kaybeden sekmelerin tamamen bellekten kaldırılmasını sağlayabilirsiniz.
useEffect ve useFocusEffect arasındaki temel fark nedir?
Temel fark, useEffect'in bileşenin mount edilmesi ve unmount edilmesiyle, useFocusEffect'in ise ekranın navigasyon bağlamında odaklanması (focus) ve odağını kaybetmesi (blur) ile ilgili olmasıdır.

  • useEffect: Bileşen DOM'a ilk kez eklendiğinde (mount) çalışır ve DOM'dan kaldırıldığında (unmount) temizleme fonksiyonunu çalıştırır. Bir ekran bir Stack Navigator'da arka plana itildiğinde unmount olmaz, bu yüzden useEffect tekrar çalışmaz.
  • useFocusEffect: Ekranın navigasyon yığınında en üstte (focused) olduğu her an çalışır. Ekran odağını kaybettiğinde (blurred) veya tamamen kaldırıldığında (unmounted) temizleme fonksiyonu çalışır. Bu, özellikle her ziyaret edildiğinde güncel veri çekilmesi gereken ekranlar için idealdir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.