CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ionic--react

React specific wrapper for @ionic/core providing React components and hooks for building cross-platform mobile applications

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

lifecycle-management.mddocs/

Lifecycle Management

React hooks and utilities for managing page lifecycle events and navigation state in mobile applications, providing fine-grained control over component behavior during page transitions.

Capabilities

Page Lifecycle Hooks

Hooks for responding to page navigation events in mobile applications.

/**
 * Hook that fires when a page has fully entered and is now the active page.
 * This will fire whether it was the first load or a page being returned to.
 * @param callback - Function to execute when page enters
 * @param deps - Dependency array for the callback (similar to useEffect)
 */
function useIonViewDidEnter(
  callback: LifeCycleCallback,
  deps?: any[]
): void;

/**
 * Hook that fires when a page is about to enter and become the active page.
 * This will fire whether it was the first load or a page being returned to.
 * @param callback - Lifecycle callback that can return a cleanup function
 * @param deps - Dependency array for the callback
 */
function useIonViewWillEnter(
  callback: LifeCycleCallback,
  deps?: any[]
): void;

/**
 * Hook that fires when a page has fully left and is no longer the active page.
 * This will fire when navigating to a new page or when the current page is being destroyed.
 * @param callback - Lifecycle callback that can return a cleanup function
 * @param deps - Dependency array for the callback
 */
function useIonViewDidLeave(
  callback: LifeCycleCallback,
  deps?: any[]
): void;

/**
 * Hook that fires when a page is about to leave and no longer be the active page.
 * This will fire when navigating to a new page or when the current page is being destroyed.
 * @param callback - Lifecycle callback that can return a cleanup function
 * @param deps - Dependency array for the callback
 */
function useIonViewWillLeave(
  callback: LifeCycleCallback,
  deps?: any[]
): void;

/**
 * Lifecycle callback interface that supports returning cleanup functions.
 */
interface LifeCycleCallback {
  (): void | (() => void | undefined);
  id?: number;
}

Higher-Order Component

Higher-order component for adding lifecycle functionality to class components.

/**
 * Higher-order component that adds Ionic lifecycle methods to class components.
 * Adds ionViewDidEnter, ionViewWillEnter, ionViewDidLeave, and ionViewWillLeave methods.
 * @param WrappedComponent - Component to wrap with lifecycle functionality
 * @returns Enhanced component with lifecycle methods
 */
function withIonLifeCycle<P extends object>(
  WrappedComponent: React.ComponentType<P>
): React.ComponentType<P>;

Lifecycle Context

Context provider and consumer for managing lifecycle state across components.

/**
 * Context interface for managing lifecycle callbacks and state.
 */
interface IonLifeCycleContextInterface {
  /** Register a callback for the ionViewDidEnter event */
  onIonViewDidEnter: (callback: LifeCycleCallback) => void;
  /** Trigger ionViewDidEnter event */
  ionViewDidEnter: () => void;
  /** Register a callback for the ionViewWillEnter event */
  onIonViewWillEnter: (callback: LifeCycleCallback) => void;
  /** Trigger ionViewWillEnter event */
  ionViewWillEnter: () => void;
  /** Register a callback for the ionViewDidLeave event */
  onIonViewDidLeave: (callback: LifeCycleCallback) => void;
  /** Trigger ionViewDidLeave event */
  ionViewDidLeave: () => void;
  /** Register a callback for the ionViewWillLeave event */
  onIonViewWillLeave: (callback: LifeCycleCallback) => void;
  /** Trigger ionViewWillLeave event */
  ionViewWillLeave: () => void;
  /** Cleanup callbacks */
  cleanupIonViewDidEnter: (callback: LifeCycleCallback) => void;
  cleanupIonViewWillEnter: (callback: LifeCycleCallback) => void;
  cleanupIonViewDidLeave: (callback: LifeCycleCallback) => void;
  cleanupIonViewWillLeave: (callback: LifeCycleCallback) => void;
}

/**
 * Default implementation of the lifecycle context.
 * Provides methods for managing lifecycle callbacks.
 */
class DefaultIonLifeCycleContext implements IonLifeCycleContextInterface {
  onIonViewDidEnter(callback: LifeCycleCallback): void;
  ionViewDidEnter(): void;
  onIonViewWillEnter(callback: LifeCycleCallback): void;
  ionViewWillEnter(): void;
  onIonViewDidLeave(callback: LifeCycleCallback): void;
  ionViewDidLeave(): void;
  onIonViewWillLeave(callback: LifeCycleCallback): void;
  ionViewWillLeave(): void;
  cleanupIonViewDidEnter(callback: LifeCycleCallback): void;
  cleanupIonViewWillEnter(callback: LifeCycleCallback): void;
  cleanupIonViewDidLeave(callback: LifeCycleCallback): void;
  cleanupIonViewWillLeave(callback: LifeCycleCallback): void;
}

/**
 * React context for providing lifecycle functionality throughout the component tree.
 */
const IonLifeCycleContext: React.Context<IonLifeCycleContextInterface>;

Usage Examples:

import React, { useState, useEffect } from 'react';
import { 
  useIonViewDidEnter, 
  useIonViewWillEnter, 
  useIonViewDidLeave, 
  useIonViewWillLeave,
  withIonLifeCycle
} from '@ionic/react';

// Functional component with lifecycle hooks
const HomePage: React.FC = () => {
  const [data, setData] = useState<any[]>([]);
  const [isActive, setIsActive] = useState(false);

  // Load data when page is about to enter
  useIonViewWillEnter(() => {
    console.log('Page will enter - preparing data');
    loadInitialData();
  });

  // Start timers/subscriptions when page has entered
  useIonViewDidEnter(() => {
    console.log('Page did enter - starting background tasks');
    setIsActive(true);
    startPeriodicRefresh();
  }, []);

  // Clean up when page is about to leave
  useIonViewWillLeave(() => {
    console.log('Page will leave - stopping background tasks');
    setIsActive(false);
    stopPeriodicRefresh();
  });

  // Final cleanup when page has left
  useIonViewDidLeave(() => {
    console.log('Page did leave - final cleanup');
    clearCache();
  });

  const loadInitialData = async () => {
    try {
      const response = await fetch('/api/data');
      const result = await response.json();
      setData(result);
    } catch (error) {
      console.error('Failed to load data:', error);
    }
  };

  const startPeriodicRefresh = () => {
    // Start interval or subscription
  };

  const stopPeriodicRefresh = () => {
    // Stop interval or subscription
  };

  const clearCache = () => {
    // Clear any cached data
    setData([]);
  };

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Home {isActive && '(Active)'}</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        {data.map((item, index) => (
          <IonItem key={index}>
            <IonLabel>{item.name}</IonLabel>
          </IonItem>
        ))}
      </IonContent>
    </IonPage>
  );
};

// Class component with lifecycle HOC
interface ProfilePageProps {
  userId: string;
}

interface ProfilePageState {
  profile: any;
  loading: boolean;
}

class ProfilePageComponent extends React.Component<ProfilePageProps, ProfilePageState> {
  private refreshInterval?: NodeJS.Timeout;

  constructor(props: ProfilePageProps) {
    super(props);
    this.state = {
      profile: null,
      loading: false
    };
  }

  ionViewWillEnter() {
    console.log('Profile page will enter');
    this.loadProfile();
  }

  ionViewDidEnter() {
    console.log('Profile page did enter');
    this.startAutoRefresh();
  }

  ionViewWillLeave() {
    console.log('Profile page will leave');
    this.stopAutoRefresh();
  }

  ionViewDidLeave() {
    console.log('Profile page did leave');
    // Additional cleanup if needed
  }

  loadProfile = async () => {
    this.setState({ loading: true });
    try {
      const response = await fetch(`/api/profile/${this.props.userId}`);
      const profile = await response.json();
      this.setState({ profile, loading: false });
    } catch (error) {
      console.error('Failed to load profile:', error);
      this.setState({ loading: false });
    }
  };

  startAutoRefresh = () => {
    this.refreshInterval = setInterval(() => {
      this.loadProfile();
    }, 30000); // Refresh every 30 seconds
  };

  stopAutoRefresh = () => {
    if (this.refreshInterval) {
      clearInterval(this.refreshInterval);
      this.refreshInterval = undefined;
    }
  };

  render() {
    const { profile, loading } = this.state;

    return (
      <IonPage>
        <IonHeader>
          <IonToolbar>
            <IonTitle>Profile</IonTitle>
          </IonToolbar>
        </IonHeader>
        <IonContent>
          {loading && <IonSpinner />}
          {profile && (
            <IonCard>
              <IonCardHeader>
                <IonCardTitle>{profile.name}</IonCardTitle>
              </IonCardHeader>
              <IonCardContent>
                <p>{profile.email}</p>
                <p>{profile.bio}</p>
              </IonCardContent>
            </IonCard>
          )}
        </IonContent>
      </IonPage>
    );
  }
}

// Wrap class component with lifecycle HOC
const ProfilePage = withIonLifeCycle(ProfilePageComponent);

// Custom hook combining lifecycle with other logic
const usePageAnalytics = (pageName: string) => {
  useIonViewDidEnter(() => {
    // Track page view
    analytics.track('page_view', { page: pageName });
  });

  useIonViewDidLeave(() => {
    // Track page exit
    analytics.track('page_exit', { page: pageName });
  });
};

// Usage of custom hook
const AnalyticsPage: React.FC = () => {
  usePageAnalytics('dashboard');

  return (
    <IonPage>
      <IonContent>
        <h1>Dashboard</h1>
      </IonContent>
    </IonPage>
  );
};

Lifecycle Event Sequence

The lifecycle events fire in the following sequence during navigation:

When entering a page:

  1. ionViewWillEnter - Page is about to enter
  2. ionViewDidEnter - Page has entered and is now active

When leaving a page:

  1. ionViewWillLeave - Page is about to leave
  2. ionViewDidLeave - Page has left and is no longer active

Best Practices

  1. Data Loading: Use useIonViewWillEnter for initial data loading to ensure it's ready when the page appears
  2. Subscriptions: Start subscriptions in useIonViewDidEnter and clean them up in useIonViewWillLeave
  3. Timers: Use lifecycle hooks to manage timers and intervals to avoid memory leaks
  4. Analytics: Track page views and user interactions using lifecycle events
  5. Performance: Clean up heavy operations when pages become inactive to improve performance

docs

core-setup.md

index.md

lifecycle-management.md

navigation-routing.md

overlay-management.md

platform-utilities.md

ui-components.md

tile.json