---
title: "Gérer les événements d'onboarding dans le SDK React Native"
description: "Gérez les événements liés à l'onboarding dans React Native avec Adapty."
---

:::warning
**Les onboardings sont dépréciés dans le SDK v4 et seront supprimés dans une prochaine version.** Ils ne reçoivent plus de correctifs ni d'améliorations. Utilisez les [flows](react-native-get-pb-paywalls) à la place : contrairement aux onboardings qui s'exécutent dans une WebView, les flows s'affichent nativement sur l'appareil — offrant des animations plus fluides, un rendu natif cohérent, des temps de chargement plus rapides et aucune dépendance au runtime WebView. Consultez [Récupérer les flows & paywalls](react-native-get-pb-paywalls) et [Afficher les flows & paywalls](react-native-present-paywalls) pour commencer.
:::

Les onboardings configurés avec le builder génèrent des événements auxquels votre application peut réagir. La manière de gérer ces événements dépend de l'approche de présentation utilisée :

- **Présentation modale** : nécessite la mise en place de gestionnaires d'événements qui traitent les événements pour toutes les vues d'onboarding
- **Composant React** : gère les événements via des paramètres de callback inline directement dans le widget

Avant de commencer, assurez-vous que :

1. Vous avez installé le [SDK React Native Adapty](sdk-installation-reactnative) version 3.8.0 ou ultérieure.
2. Vous avez [créé un onboarding](create-onboarding).
3. Vous avez ajouté l'onboarding à un [placement](placements).

Pour contrôler ou surveiller les processus se déroulant sur l'écran d'onboarding dans votre application mobile, implémentez des gestionnaires d'événements :

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

Pour le composant React, vous gérez les événements via des props de gestionnaire d'événements individuels dans le composant `AdaptyOnboardingView` :

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const onAnalytics = useCallback<OnboardingEventHandlers['onAnalytics']>((event, meta) => {}, []);
  const onClose = useCallback<OnboardingEventHandlers['onClose']>((actionId, meta) => {}, []);
  const onCustom = useCallback<OnboardingEventHandlers['onCustom']>((actionId, meta) => {}, []);
  const onPaywall = useCallback<OnboardingEventHandlers['onPaywall']>((actionId, meta) => {}, []);
  const onStateUpdated = useCallback<OnboardingEventHandlers['onStateUpdated']>((action, meta) => {}, []);
  const onFinishedLoading = useCallback<OnboardingEventHandlers['onFinishedLoading']>((meta) => {}, []);
  const onError = useCallback<OnboardingEventHandlers['onError']>((error) => {}, []);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onAnalytics={onAnalytics}
      onClose={onClose}
      onCustom={onCustom}
      onPaywall={onPaywall}
      onStateUpdated={onStateUpdated}
      onFinishedLoading={onFinishedLoading}
      onError={onError}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

Pour la présentation modale, implémentez la méthode de gestionnaires d'événements.

:::important
Appeler `setEventHandlers` plusieurs fois écrasera les gestionnaires que vous avez définis, remplaçant à la fois les gestionnaires par défaut et ceux précédemment configurés pour ces événements spécifiques.
:::

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onAnalytics(event, meta) {
    // Track analytics events
  },
  onClose(actionId, meta) {
    // Handle close action
    view.dismiss();
    return true;
  },
  onCustom(actionId, meta) {
    // Handle custom actions
  },
  onPaywall(actionId, meta) {
    // Handle paywall actions
  },
  onStateUpdated(action, meta) {
    // Handle user input updates
  },
  onFinishedLoading(meta) {
    // Onboarding finished loading
  },
  onError(error) {
    // Handle loading errors
  },
});

try {
  await view.present();
} catch (error) {
  // handle the error
}
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

Pour les versions du SDK antérieures à 3.14, seule la présentation modale est prise en charge :

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onAnalytics(event, meta) {
    // Track analytics events
  },
  onClose(actionId, meta) {
    // Handle close action
    view.dismiss();
    return true;
  },
  onCustom(actionId, meta) {
    // Handle custom actions
  },
  onPaywall(actionId, meta) {
    // Handle paywall actions
  },
  onStateUpdated(action, meta) {
    // Handle user input updates
  },
  onFinishedLoading(meta) {
    // Onboarding finished loading
  },
  onError(error) {
    // Handle loading errors
  },
});

try {
  await view.present();
} catch (error) {
  // handle the error
}
```

</TabItem>
</Tabs>

## Types d'événements \{#event-types\}

Les sections suivantes décrivent les différents types d'événements que vous pouvez gérer, quelle que soit l'approche de présentation utilisée.

### Gérer les actions personnalisées \{#handle-custom-actions\}

Dans le builder, vous pouvez ajouter une action **custom** à un bouton et lui attribuer un ID.

  <img src="/assets/shared/img/ios-events-1.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

Vous pouvez ensuite utiliser cet ID dans votre code et le gérer comme une action personnalisée. Par exemple, si un utilisateur appuie sur un bouton personnalisé, comme **Login** ou **Allow notifications**, le gestionnaire d'événements sera déclenché avec le paramètre `actionId` correspondant à l'**Action ID** défini dans le builder. Vous pouvez créer vos propres IDs, comme "allowNotifications".

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const onCustom = useCallback<OnboardingEventHandlers['onCustom']>((actionId, meta) => {
    switch (actionId) {
      case 'login':
        login();
        break;
      case 'allow_notifications':
        allowNotifications();
        break;
    }
  }, []);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onCustom={onCustom}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onCustom(actionId, meta) {
    switch (actionId) {
      case 'login':
        login();
        break;
      case 'allow_notifications':
        allowNotifications();
        break;
    }
  },
});
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onCustom(actionId, meta) {
    switch (actionId) {
      case 'login':
        login();
        break;
      case 'allow_notifications':
        allowNotifications();
        break;
    }
  },
});
```

</TabItem>
</Tabs>

<Details>
<summary>Exemple d'événement (cliquez pour développer)</summary>

```json
{
  "actionId": "allow_notifications",
  "meta": {
    "onboardingId": "onboarding_123",
    "screenClientId": "profile_screen",
    "screenIndex": 0,
    "screensTotal": 3
  }
}
```
</Details>

### Fin du chargement de l'onboarding \{#finishing-loading-onboarding\}

Cet événement est déclenché lorsque le chargement d'un onboarding est terminé :

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const onFinishedLoading = useCallback<OnboardingEventHandlers['onFinishedLoading']>((meta) => {
    console.log('Onboarding loaded:', meta.onboardingId);
  }, []);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onFinishedLoading={onFinishedLoading}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onFinishedLoading(meta) {
    console.log('Onboarding loaded:', meta.onboardingId);
  },
});
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onFinishedLoading(meta) {
    console.log('Onboarding loaded:', meta.onboardingId);
  },
});
```

</TabItem>
</Tabs>

<Details>
<summary>Exemple d'événement (cliquez pour développer)</summary>

```json
{
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "welcome_screen",
        "screen_index": 0,
        "total_screens": 4
    }
}
```
</Details>

### Fermeture de l'onboarding \{#closing-onboarding\}

L'onboarding est considéré comme fermé lorsqu'un utilisateur appuie sur un bouton auquel l'action **Close** est assignée.

  <img src="/assets/shared/img/ios-events-2.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

:::important
Notez que vous devez gérer ce qui se passe lorsqu'un utilisateur ferme l'onboarding. Par exemple, vous devez arrêter d'afficher l'onboarding lui-même.
:::

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding, navigation }) {
  const onClose = useCallback<OnboardingEventHandlers['onClose']>((actionId, meta) => {
    navigation.goBack();  
  }, [navigation]);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onClose={onClose}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onClose(actionId, meta) {
    await view.dismiss();
    return true;
  },
});
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onClose(actionId, meta) {
    await view.dismiss();
    return true;
  },
});
```

</TabItem>
</Tabs>

<Details>
<summary>Exemple d'événement (cliquez pour développer)</summary>

```json
{
  "action_id": "close_button",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "final_screen",
    "screen_index": 3,
    "total_screens": 4
  }
}
```
</Details>

### Ouverture d'un paywall \{#opening-a-paywall\}

:::tip
Gérez cet événement pour ouvrir un paywall à l'intérieur de l'onboarding. Si vous souhaitez ouvrir un paywall après sa fermeture, il existe une méthode plus simple : gérez l'action de fermeture et ouvrez un paywall sans vous appuyer sur les données de l'événement.
:::

La façon la plus fluide de travailler avec les paywalls dans les onboardings est de faire correspondre l'ID d'action à un ID de placement de paywall.

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const onPaywall = useCallback<OnboardingEventHandlers['onPaywall']>((actionId, meta) => {
    openPaywall(actionId);
  }, []);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onPaywall={onPaywall}
    />
  );
}

const openPaywall = async (placementId) => {
  // Implement your paywall opening logic here
};
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

Notez que, sur iOS, une seule vue (paywall ou onboarding) peut être affichée à l'écran à la fois. Si vous affichez un paywall par-dessus un onboarding, vous ne pouvez pas contrôler l'onboarding en arrière-plan par programmation. Tenter de fermer l'onboarding fermera le paywall à la place, laissant l'onboarding visible. Pour éviter cela, fermez toujours la vue d'onboarding avant de présenter le paywall.

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onPaywall(actionId, meta) {
    view.dismiss().then(() => {
      openPaywall(actionId);
    });
  },
});

const openPaywall = async (placementId) => {
  // Implement your paywall opening logic here
};
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

Notez que, sur iOS, une seule vue (paywall ou onboarding) peut être affichée à l'écran à la fois. Si vous affichez un paywall par-dessus un onboarding, vous ne pouvez pas contrôler l'onboarding en arrière-plan par programmation. Tenter de fermer l'onboarding fermera le paywall à la place, laissant l'onboarding visible. Pour éviter cela, fermez toujours la vue d'onboarding avant de présenter le paywall.

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onPaywall(actionId, meta) {
    view.dismiss().then(() => {
      openPaywall(actionId);
    });
  },
});

const openPaywall = async (placementId) => {
  // Implement your paywall opening logic here
};
```

</TabItem>
</Tabs>

<Details>
<summary>Exemple d'événement (cliquez pour développer)</summary>

```json
{
    "action_id": "premium_offer_1",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "pricing_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}
```
</Details>

### Suivi de la navigation \{#tracking-navigation\}

Vous recevez un événement d'analytics lorsque divers événements liés à la navigation se produisent pendant le flow d'onboarding :

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const onAnalytics = useCallback<OnboardingEventHandlers['onAnalytics']>((event, meta) => {
    trackEvent(event.name, meta.onboardingId);
  }, []);

  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={styles.container}
      onAnalytics={onAnalytics}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.setEventHandlers({
  onAnalytics(event, meta) {
    trackEvent(event.name, meta.onboardingId);
  },
});
```

</TabItem>
</Tabs>

</TabItem>

<TabItem value="old" label="SDK version < 3.14">

```javascript showLineNumbers title="React Native"

const view = await createOnboardingView(onboarding);

const unsubscribe = view.registerEventHandlers({
  onAnalytics(event, meta) {
    trackEvent(event.name, meta.onboardingId);
  },
});
```

</TabItem>
</Tabs>

L'objet `event` peut être l'un des types suivants :

|Type | Description |
|------------|-------------|
| `onboardingStarted` | Lorsque l'onboarding a été chargé |
| `screenPresented` | Lorsqu'un écran est affiché |
| `screenCompleted` | Lorsqu'un écran est terminé. Inclut un `elementId` optionnel (identifiant de l'élément terminé) et une `reply` optionnelle (réponse de l'utilisateur). Déclenché lorsque les utilisateurs effectuent une action pour quitter l'écran. |
| `secondScreenPresented` | Lorsque le deuxième écran est affiché |
| `userEmailCollected` | Déclenché lorsque l'adresse e-mail de l'utilisateur est collectée via le champ de saisie |
| `onboardingCompleted` | Déclenché lorsqu'un utilisateur atteint un écran avec l'ID `final`. Si vous avez besoin de cet événement, [attribuez l'ID `final` au dernier écran](design-onboarding). |
| `unknown` | Pour tout type d'événement non reconnu. Inclut `name` (le nom de l'événement inconnu) et `meta` (métadonnées supplémentaires) |

Chaque événement inclut des informations `meta` contenant :

| Champ | Description |
|------------|-------------|
| `onboardingId` | Identifiant unique du flow d'onboarding |
| `screenClientId` | Identifiant de l'écran actuel |
| `screenIndex` | Position de l'écran actuel dans le flow |
| `screensTotal` | Nombre total d'écrans dans le flow |

<Details>
<summary>Exemples d'événements (cliquez pour développer)</summary>

```javascript
// onboardingStarted
{
  "name": "onboarding_started",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "welcome_screen",
    "screen_index": 0,
    "total_screens": 4
  }
}

// screenPresented
{
    "name": "screen_presented",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "interests_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}

// screenCompleted
{
    "name": "screen_completed",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    },
    "params": {
        "element_id": "profile_form",
        "reply": "success"
    }
}

// secondScreenPresented
{
    "name": "second_screen_presented",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    }
}

// userEmailCollected
{
    "name": "user_email_collected",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    }
}

// onboardingCompleted
{
    "name": "onboarding_completed",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "final_screen",
        "screen_index": 3,
        "total_screens": 4
    }
}
```
</Details>