Skip to content

t-code4change/react-native-global-event

Repository files navigation

React Native Global Event

πŸš€ The Ultimate Solution for React Native Component Communication

A powerful and lightweight global event system designed specifically for React Native applications. Solve complex component communication issues, eliminate prop drilling, enable seamless cross-component function calls, and integrate perfectly with Redux/Saga workflows.

🎯 What This Library Solves

React Native developers face unique challenges:

  • Deep Navigation Stacks: Components buried 5+ screens deep need to communicate with root components
  • Redux/Saga Integration: Trigger component functions from Redux actions or Saga effects
  • Cross-Screen Communication: Components on different screens need to interact
  • Navigation Events: Handle navigation events across the entire app
  • State Synchronization: Keep multiple components in sync with global state changes
  • Background/Foreground Events: Handle app state changes across all components
  • Push Notification Handling: Distribute notification events to relevant components
  • Deep Linking: Route deep link events to appropriate components

πŸš€ Key Features

  • 🎯 React Native Optimized: Built specifically for React Native performance and patterns
  • πŸ”„ Redux/Saga Integration: Seamlessly trigger component functions from Redux actions
  • πŸ“± Navigation Support: Perfect for React Navigation and deep navigation stacks
  • ⚑ Performance Optimized: Lightweight with minimal bundle impact
  • πŸ›‘οΈ TypeScript Support: Full TypeScript support with comprehensive type definitions
  • πŸŽ›οΈ Dual API: Class-based and Hook-based APIs for different use cases
  • πŸ”§ Priority System: Execute listeners in priority order
  • πŸ“¦ Scoped Events: Organize events with namespaces for better structure
  • 🧹 Automatic Cleanup: Hooks automatically clean up listeners on unmount
  • ⚠️ Error Handling: Graceful error handling with optional warnings

πŸ“¦ Installation

npm install react-native-global-event
yarn add react-native-global-event

🎯 React Native Use Cases

1. Redux/Saga Integration - Trigger Components from Redux Actions

Problem: You have Redux actions that need to trigger UI updates in specific components, but those components aren't connected to Redux.

// Redux Action
const loginUser = (userData) => ({
  type: 'LOGIN_USER',
  payload: userData
});

// Saga Effect
function* loginUserSaga(action) {
  try {
    const userData = yield call(api.login, action.payload);
    yield put({ type: 'LOGIN_SUCCESS', payload: userData });
    
    // πŸš€ Trigger component functions via global event
    globalEvent.emit('redux-user-login', userData);
  } catch (error) {
    globalEvent.emit('redux-login-error', error);
  }
}

// Component that reacts to Redux events
function UserProfile() {
  const [user, setUser] = useState(null);

  useGlobalEventListener('redux-user-login', (userData) => {
    setUser(userData);
    // Show success animation, update UI, etc.
  });

  useGlobalEventListener('redux-login-error', (error) => {
    // Show error message, reset form, etc.
  });

  return user ? <Text>Welcome, {user.name}!</Text> : <Text>Please login</Text>;
}

2. Deep Navigation Communication - Child to Parent Across Screens

Problem: A component deep in your navigation stack needs to communicate with a component on the root screen.

// Deep nested component (5+ screens deep)
function DeepNestedComponent() {
  const { emit } = useGlobalEvent();

  const handleUserAction = (action) => {
    // πŸš€ Communicate with root component without prop drilling
    emit('user-action', { action, timestamp: Date.now() });
  };

  return (
    <TouchableOpacity onPress={() => handleUserAction('profile-updated')}>
      <Text>Update Profile</Text>
    </TouchableOpacity>
  );
}

// Root component that listens to deep events
function RootComponent() {
  const [notifications, setNotifications] = useState([]);

  useGlobalEventListener('user-action', (data) => {
    setNotifications(prev => [...prev, data]);
    // Show toast, update badge, etc.
  });

  return (
    <View>
      <Text>Notifications: {notifications.length}</Text>
      {/* Your app content */}
    </View>
  );
}

3. Cross-Screen Communication - Components on Different Screens

Problem: Components on different screens need to communicate with each other.

// Screen A - Product List
function ProductListScreen() {
  const { emit } = useGlobalEvent();

  const addToCart = (product) => {
    // πŸš€ Notify cart screen about new item
    emit('product-added-to-cart', product);
  };

  return (
    <FlatList
      data={products}
      renderItem={({ item }) => (
        <TouchableOpacity onPress={() => addToCart(item)}>
          <Text>Add {item.name} to Cart</Text>
        </TouchableOpacity>
      )}
    />
  );
}

// Screen B - Cart Screen
function CartScreen() {
  const [cartItems, setCartItems] = useState([]);

  useGlobalEventListener('product-added-to-cart', (product) => {
    setCartItems(prev => [...prev, product]);
    // Show success animation, update badge, etc.
  });

  return (
    <View>
      <Text>Cart Items: {cartItems.length}</Text>
      {/* Cart content */}
    </View>
  );
}

4. Navigation Events - Handle Navigation Across App

Problem: You need to handle navigation events from anywhere in your app.

// Navigation service
class NavigationService {
  static navigate(screenName, params) {
    // Your navigation logic
    globalEvent.emit('navigation-requested', { screenName, params });
  }
}

// Component that handles navigation
function NavigationHandler() {
  useGlobalEventListener('navigation-requested', ({ screenName, params }) => {
    // Handle navigation logic
    navigation.navigate(screenName, params);
  });

  return null; // This is a service component
}

// Any component can trigger navigation
function AnyComponent() {
  const { emit } = useGlobalEvent();

  const goToProfile = () => {
    emit('navigation-requested', { screenName: 'Profile', params: { userId: 123 } });
  };

  return (
    <TouchableOpacity onPress={goToProfile}>
      <Text>Go to Profile</Text>
    </TouchableOpacity>
  );
}

5. App State Management - Background/Foreground Events

Problem: Handle app state changes across all components.

// App state handler
function AppStateHandler() {
  useEffect(() => {
    const handleAppStateChange = (nextAppState) => {
      globalEvent.emit('app-state-changed', { state: nextAppState });
    };

    const subscription = AppState.addEventListener('change', handleAppStateChange);
    return () => subscription?.remove();
  }, []);

  return null;
}

// Components that react to app state changes
function DataSyncComponent() {
  useGlobalEventListener('app-state-changed', ({ state }) => {
    if (state === 'active') {
      // Sync data when app becomes active
      syncData();
    }
  });

  return <Text>Data Sync Component</Text>;
}

6. Push Notification Handling - Distribute Notifications

Problem: Handle push notifications and distribute them to relevant components.

// Push notification handler
function PushNotificationHandler() {
  useEffect(() => {
    const handleNotification = (notification) => {
      globalEvent.emit('push-notification-received', notification);
    };

    // Your push notification setup
    return () => {
      // Cleanup
    };
  }, []);

  return null;
}

// Components that handle specific notifications
function ChatComponent() {
  useGlobalEventListener('push-notification-received', (notification) => {
    if (notification.type === 'chat') {
      // Handle chat notification
      updateChatList(notification.data);
    }
  });

  return <Text>Chat Component</Text>;
}

7. Deep Linking - Route Deep Link Events

Problem: Handle deep links and route them to appropriate components.

// Deep link handler
function DeepLinkHandler() {
  useEffect(() => {
    const handleDeepLink = (url) => {
      globalEvent.emit('deep-link-received', { url });
    };

    // Your deep link setup
    return () => {
      // Cleanup
    };
  }, []);

  return null;
}

// Components that handle deep links
function ProductDetailComponent() {
  useGlobalEventListener('deep-link-received', ({ url }) => {
    if (url.includes('/product/')) {
      const productId = extractProductId(url);
      // Navigate to product detail
      navigateToProduct(productId);
    }
  });

  return <Text>Product Detail Component</Text>;
}

8. Multiple Components, Same Action - Synchronized Updates

Problem: Multiple components need to perform the same action simultaneously.

// Component A - User Profile
function UserProfile() {
  const [user, setUser] = useState(null);

  useGlobalEventListener('user-data-updated', (userData) => {
    setUser(userData);
    // Update profile UI
  });

  return <Text>Profile: {user?.name}</Text>;
}

// Component B - User Settings
function UserSettings() {
  const [user, setUser] = useState(null);

  useGlobalEventListener('user-data-updated', (userData) => {
    setUser(userData);
    // Update settings UI
  });

  return <Text>Settings for: {user?.name}</Text>;
}

// Component C - User Dashboard
function UserDashboard() {
  const [user, setUser] = useState(null);

  useGlobalEventListener('user-data-updated', (userData) => {
    setUser(userData);
    // Update dashboard UI
  });

  return <Text>Dashboard for: {user?.name}</Text>;
}

// Trigger update from anywhere
function UpdateUserButton() {
  const { emit } = useGlobalEvent();

  const updateUser = () => {
    const newUserData = { name: 'John Doe', email: 'john@example.com' };
    // πŸš€ All three components will update simultaneously
    emit('user-data-updated', newUserData);
  };

  return (
    <TouchableOpacity onPress={updateUser}>
      <Text>Update User</Text>
    </TouchableOpacity>
  );
}

πŸš€ Quick Start

Basic Usage

import { globalEvent } from 'react-native-global-event';

// Emit an event
globalEvent.emit('user-login', { userId: 123, username: 'john' });

// Listen to an event
const subscription = globalEvent.on('user-login', (userData) => {
  console.log('User logged in:', userData);
});

// Clean up
subscription.remove();

React Native Hook Usage

import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useGlobalEvent, useGlobalEventListener } from 'react-native-global-event';

function MyComponent() {
  const { emit } = useGlobalEvent();

  useGlobalEventListener('data-loaded', (data) => {
    console.log('Data received:', data);
  });

  const handlePress = () => {
    emit('button-pressed', { timestamp: Date.now() });
  };

  return (
    <TouchableOpacity onPress={handlePress}>
      <Text>Press Me</Text>
    </TouchableOpacity>
  );
}

πŸ“š API Reference

Class-based API

GlobalEvent

The main class for managing global events.

import { GlobalEvent } from 'react-native-global-event';

const globalEvent = new GlobalEvent();

Methods:

  • emit<T>(eventName: string, data?: T): void - Emit an event
  • on<T>(eventName: string, listener: EventListener<T>, options?: { once?: boolean; priority?: number }): EventSubscription - Register a listener
  • off<T>(eventName: string, listener?: EventListener<T> | string): void - Remove a listener
  • once<T>(eventName: string, listener: EventListener<T>): EventSubscription - Register a one-time listener
  • removeAllListeners(eventName?: string): void - Remove all listeners
  • getListenerCount(eventName: string): number - Get listener count
  • getEventNames(): string[] - Get all event names
  • scope(namespace: string): ScopedGlobalEvent - Create a scoped event manager
  • batchEmit(events: Array<{ name: string; data?: any }>): void - Emit multiple events

ScopedGlobalEvent

Namespace-aware event manager for better organization.

const userEvents = globalEvent.scope('user');
userEvents.emit('login', userData); // Actually emits 'user:login'

Hook-based API

useGlobalEvent

Main hook for event management with automatic cleanup.

const { emit, on, off, once, removeAllListeners, getListenerCount, getEventNames } = useGlobalEvent();

useGlobalEventListener

Hook for listening to a specific event with automatic cleanup.

useGlobalEventListener('user-login', (userData) => {
  console.log('User logged in:', userData);
}, [dependency]);

useGlobalEventOnce

Hook for one-time event listening.

useGlobalEventOnce('initial-data-loaded', (data) => {
  console.log('Initial data loaded:', data);
});

useScopedGlobalEvent

Hook for scoped event management.

const userEvents = useScopedGlobalEvent('user');
userEvents.emit('login', userData);

useGlobalEventState

Hook for managing component state based on events.

const [userData, setUserData] = useGlobalEventState('user-updated', null);
const [isOnline, setIsOnline] = useGlobalEventState(
  'connection-status',
  false,
  (data) => data.status === 'connected'
);

πŸ”§ Configuration

EventManager Options

import { EventManager } from 'react-native-global-event';

const eventManager = EventManager.getInstance({
  maxListeners: 50,        // Maximum listeners per event
  enableWarnings: true     // Enable console warnings
});

Priority System

// Higher priority listeners execute first
globalEvent.on('data-loaded', highPriorityHandler, { priority: 10 });
globalEvent.on('data-loaded', normalHandler, { priority: 5 });
globalEvent.on('data-loaded', lowPriorityHandler, { priority: 1 });

πŸ§ͺ Testing

The library includes comprehensive unit tests. Run tests with:

npm test
npm run test:coverage

πŸ“Š Performance

  • Lightweight: Minimal bundle size impact
  • Efficient: Optimized event handling and cleanup
  • Memory Safe: Automatic cleanup prevents memory leaks
  • Type Safe: Full TypeScript support for better development experience

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built specifically for React Native developers
  • Inspired by the need to solve complex component communication in React Native applications
  • Comprehensive testing ensures reliability
  • Made with ❀️ for the React Native community

πŸš€ Made with ❀️ for React Native developers

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages