← Bloga Dön

React Native'de İnternet Bağlantı Kontrolü

·5 dk okuma
React NativeNetInfoProviderContext APIInternet

React Native'de İnternet Bağlantı Kontrolü

Mobil uygulamalarda en sık karşılaşılan senaryolardan biri, kullanıcının internet bağlantısının kopmasıdır. Kullanıcıya bunu anında bildirmek, kötü bir deneyimi önlemenin en basit yoludur. Bu yazıda @react-native-community/netinfo paketini kullanarak uygulamanın her yerinden erişilebilen bir InternetCheckProvider yazacağız.

@react-native-community/netinfo Nedir?

@react-native-community/netinfo, cihazın ağ durumunu izlemenizi sağlayan bir React Native kütüphanesidir. Size şu bilgileri verir:

  • Cihaz internete bağlı mı? (isConnected)
  • İnternet gerçekten erişilebilir mi? (isInternetReachable)
  • Bağlantı tipi nedir? (WiFi, Cellular, Ethernet, vb.)
  • Bağlantı detayları (frekans, sinyal gücü, vb.)

Önemli: isConnected sadece bir ağa bağlı olduğunuzu söyler. WiFi'ye bağlı olup interneti olmayan bir ağda isConnected: true ama isInternetReachable: false döner. Bu yüzden gerçek internet kontrolü için isInternetReachable kullanacağız.

Kurulum

npm install @react-native-community/netinfo

Expo kullanıyorsanız:

npx expo install @react-native-community/netinfo

iOS için pod kurulumunu unutmayın:

cd ios && pod install

InternetCheckProvider Yazalım

Amacımız şu: uygulama genelinde internet durumunu izleyen, bağlantı kesildiğinde ekranın üstünden bir uyarı bandı gösteren ve bağlantı geri geldiğinde bunu otomatik kapatan bir yapı kurmak.

1. Context Oluşturma

Önce internet durumunu tutacak bir context oluşturalım:

// src/contexts/InternetCheckContext.tsx
import { createContext, useContext } from "react";

interface InternetCheckContextType {
  isConnected: boolean;
}

export const InternetCheckContext = createContext<InternetCheckContextType>({
  isConnected: true,
});

export const useInternetCheck = () => useContext(InternetCheckContext);

2. Provider Bileşeni

Şimdi asıl provider'ı yazalım. NetInfo'nun addEventListener metoduyla bağlantı değişikliklerini dinleyeceğiz:

// src/providers/InternetCheckProvider.tsx
import React, { useEffect, useState, useCallback, useRef } from "react";
import {
  View,
  Text,
  StyleSheet,
  Animated,
  Platform,
} from "react-native";
import NetInfo, { NetInfoState } from "@react-native-community/netinfo";
import { InternetCheckContext } from "../contexts/InternetCheckContext";

interface Props {
  children: React.ReactNode;
}

export const InternetCheckProvider: React.FC<Props> = ({ children }) => {
  const [isConnected, setIsConnected] = useState(true);
  const slideAnim = useRef(new Animated.Value(-60)).current;

  const showBanner = useCallback(() => {
    Animated.timing(slideAnim, {
      toValue: 0,
      duration: 300,
      useNativeDriver: true,
    }).start();
  }, [slideAnim]);

  const hideBanner = useCallback(() => {
    Animated.timing(slideAnim, {
      toValue: -60,
      duration: 300,
      useNativeDriver: true,
    }).start();
  }, [slideAnim]);

  useEffect(() => {
    const unsubscribe = NetInfo.addEventListener((state: NetInfoState) => {
      const connected = state.isInternetReachable ?? state.isConnected ?? true;

      setIsConnected(connected);

      if (!connected) {
        showBanner();
      } else {
        hideBanner();
      }
    });

    return () => unsubscribe();
  }, [showBanner, hideBanner]);

  return (
    <InternetCheckContext.Provider value={{ isConnected }}>
      {children}
      <Animated.View
        style={[
          styles.banner,
          { transform: [{ translateY: slideAnim }] },
        ]}
      >
        <View style={styles.content}>
          <Text style={styles.icon}>📡</Text>
          <Text style={styles.text}>İnternet bağlantısı yok</Text>
        </View>
      </Animated.View>
    </InternetCheckContext.Provider>
  );
};

const styles = StyleSheet.create({
  banner: {
    position: "absolute",
    top: 0,
    left: 0,
    right: 0,
    backgroundColor: "#DC2626",
    paddingTop: Platform.OS === "ios" ? 50 : 30,
    paddingBottom: 12,
    paddingHorizontal: 16,
    zIndex: 9999,
  },
  content: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    gap: 8,
  },
  icon: {
    fontSize: 16,
  },
  text: {
    color: "#FFFFFF",
    fontSize: 14,
    fontWeight: "600",
  },
});

Burada dikkat etmeniz gereken birkaç şey var:

  • isInternetReachable kullanıyoruz, sadece isConnected değil. Böylece WiFi'ye bağlı ama interneti olmayan durumları da yakalıyoruz.
  • Animated.Value ile banner yukarıdan aşağı kayarak geliyor. Kullanıcı deneyimi açısından ani bir görünüp kaybolmaktan çok daha iyi.
  • zIndex: 9999 ile banner her şeyin üstünde kalıyor.
  • Platform.OS kontrolü ile iOS'taki status bar yüksekliği hesaba katılıyor.

3. App'e Entegre Etme

Provider'ı uygulamanın en üst seviyesine sarıyoruz:

// App.tsx
import React from "react";
import { InternetCheckProvider } from "./src/providers/InternetCheckProvider";
import { Navigation } from "./src/navigation";

export default function App() {
  return (
    <InternetCheckProvider>
      <Navigation />
    </InternetCheckProvider>
  );
}

4. Herhangi Bir Ekranda Kullanma

Artık uygulamanın herhangi bir yerinden internet durumunu okuyabilirsiniz:

import { useInternetCheck } from "../contexts/InternetCheckContext";

function ProfileScreen() {
  const { isConnected } = useInternetCheck();

  const handleSave = () => {
    if (!isConnected) {
      Alert.alert("Hata", "Bu işlem için internet bağlantısı gerekli.");
      return;
    }

    // API çağrısı yap
  };

  return (
    <View>
      <Button title="Kaydet" onPress={handleSave} />
    </View>
  );
}

Bağlantı Geri Geldiğinde Bildirim

İsterseniz bağlantı geri geldiğinde de kısa bir süre yeşil bir banner gösterebilirsiniz. Provider'a küçük bir ekleme yapalım:

const [showReconnected, setShowReconnected] = useState(false);
const wasDisconnected = useRef(false);

useEffect(() => {
  const unsubscribe = NetInfo.addEventListener((state: NetInfoState) => {
    const connected = state.isInternetReachable ?? state.isConnected ?? true;

    if (!connected) {
      wasDisconnected.current = true;
      setIsConnected(false);
      showBanner();
    } else {
      if (wasDisconnected.current) {
        // Bağlantı geri geldi
        setShowReconnected(true);
        setIsConnected(true);
        showBanner();

        setTimeout(() => {
          hideBanner();
          setShowReconnected(false);
          wasDisconnected.current = false;
        }, 2000);
      } else {
        setIsConnected(true);
        hideBanner();
      }
    }
  });

  return () => unsubscribe();
}, [showBanner, hideBanner]);

Banner rengini de duruma göre değiştirin:

<Animated.View
  style={[
    styles.banner,
    {
      transform: [{ translateY: slideAnim }],
      backgroundColor: showReconnected ? "#16A34A" : "#DC2626",
    },
  ]}
>
  <View style={styles.content}>
    <Text style={styles.icon}>{showReconnected ? "✅" : "📡"}</Text>
    <Text style={styles.text}>
      {showReconnected ? "Bağlantı yeniden sağlandı" : "İnternet bağlantısı yok"}
    </Text>
  </View>
</Animated.View>

NetInfo Konfigürasyonu

NetInfo'nun internet erişilebilirlik kontrolünü özelleştirebilirsiniz:

NetInfo.configure({
  reachabilityUrl: "https://clients3.google.com/generate_204",
  reachabilityTest: async (response) => response.status === 204,
  reachabilityLongTimeout: 60 * 1000,   // 60 saniye
  reachabilityShortTimeout: 5 * 1000,   // 5 saniye
  reachabilityRequestTimeout: 15 * 1000, // 15 saniye
});

Bu konfigürasyonu uygulamanın en başında (provider'dan önce) çağırmanız yeterli.

Özet

Bu yazıda şunları yaptık:

  1. @react-native-community/netinfo paketini kurduk
  2. Internet durumunu izleyen bir Context + Provider yapısı oluşturduk
  3. Bağlantı kesildiğinde yukarıdan kayan kırmızı bir banner gösterdik
  4. Bağlantı geri geldiğinde yeşil bir bildirim ekledik
  5. useInternetCheck hook'u ile herhangi bir ekrandan internet durumunu okuduk

Bu yapı production uygulamalarda sıkça kullanılır ve kullanıcı deneyimini önemli ölçüde iyileştirir. Kullanıcı internet olmadan bir işlem yapmaya çalışmadan önce durumdan haberdar olur.