# Network connectivity is actively detected

- **Pattern:** `ab-001876` (`mobile-offline-storage.offline-behavior.network-detection`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001876
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001876)

## Why it matters

Without active network detection, your app has no basis for deciding when to serve cached data, queue actions, or display an offline banner. Blind network calls on a disconnected device generate unhandled promise rejections that ripple into broken UI states. ISO 25010:2011 reliability.fault-tolerance requires apps to detect and respond to connection loss at runtime. The absence of a NetInfo or equivalent listener means every network-dependent feature silently fails rather than gracefully degrading — a qualitatively worse user experience than a clear offline indicator.

## Severity rationale

High because without connectivity detection, all network-dependent features fail silently, leaving users with no feedback and no path to offline functionality.

## Remediation

Register a `NetInfo.addEventListener` at app startup and store connection state in a shared hook. Every screen that needs network access reads from this hook before attempting a fetch.

```tsx
// npm install @react-native-community/netinfo
import NetInfo from '@react-native-community/netinfo';
import { useEffect, useState } from 'react';

export function useNetworkStatus() {
  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {
    const unsub = NetInfo.addEventListener(state => {
      setIsOnline(state.isConnected ?? false);
    });
    return unsub;
  }, []);

  return isOnline;
}
```

Then gate network calls on this value and show an `<OfflineBanner />` when `isOnline` is false. Wire this listener before your root navigator mounts so the value is stable on first render.

## Detection

- **ID:** `network-detection`
- **Severity:** `high`
- **What to look for:** Examine whether the app uses a network detection library like netinfo or expo-network. Look for code that listens to network state changes (connected/disconnected, wifi/cellular/none) and responds accordingly.
- **Pass criteria:** Count all network state listener registrations in the codebase. App imports and uses a network detection library with at least 1 active listener that updates app state when connection changes. The listener must differentiate between connected and disconnected states.
- **Fail criteria:** No network detection library found, or the library is imported but not used. Do NOT pass when the network library is imported but no addEventListener or equivalent listener is registered.
- **Skip (N/A) when:** Never — knowing network status is essential for offline handling.
- **Cross-reference:** The Mobile Navigation & Deep Linking audit (`mobile-navigation-linking`) checks navigation state persistence, which depends on network-aware state management.
- **Detail on fail:** `"No network detection library found. App cannot differentiate between online and offline states."`
- **Remediation:** Use react-native-netinfo to monitor network state:

  ```tsx
  // Install: npm install @react-native-community/netinfo

  import NetInfo from '@react-native-community/netinfo';
  import { useEffect, useState } from 'react';

  export function useNetworkStatus() {
    const [isOnline, setIsOnline] = useState(true);

    useEffect(() => {
      const unsubscribe = NetInfo.addEventListener(state => {
        setIsOnline(state.isConnected ?? false);
      });

      return unsubscribe;
    }, []);

    return isOnline;
  }

  // Usage in your app:
  export function MyScreen() {
    const isOnline = useNetworkStatus();

    return (
      <View>
        {!isOnline && <OfflineBanner />}
        {/* ... rest of UI ... */}
      </View>
    );
  }
  ```

  Or use Expo's built-in network module:

  ```tsx
  import * as Network from 'expo-network';

  export async function checkConnection() {
    const result = await Network.getNetworkStateAsync();
    return result.isConnected ?? false;
  }
  ```

## External references

- iso-25010 reliability.fault-tolerance

Taxons: error-resilience

HTML version: https://auditbuffet.com/patterns/ab-001876
