---
title: "Presentar onboardings en el SDK de React Native"
description: "Descubre cómo presentar onboardings en React Native para aumentar conversiones e ingresos."
---

:::warning
**Los onboardings están obsoletos en el SDK v4 y se eliminarán en una versión futura.** Ya no reciben correcciones ni mejoras. Usa [flows](react-native-get-pb-paywalls) en su lugar: a diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo, lo que ofrece animaciones más fluidas, una apariencia nativa coherente, tiempos de carga más rápidos y sin dependencia del entorno WebView. Consulta [Obtener flows y paywalls](react-native-get-pb-paywalls) y [Mostrar flows y paywalls](react-native-present-paywalls) para empezar.
:::
Si has personalizado un onboarding usando el builder, no necesitas preocuparte por renderizarlo en el código de tu aplicación móvil para mostrárselo al usuario. Ese onboarding incluye tanto lo que debe mostrarse como la forma en que debe mostrarse.

Antes de empezar, asegúrate de que:

1. Tienes instalado el [SDK de Adapty para React Native](sdk-installation-reactnative) 3.8.0 o posterior.
2. Has [creado un onboarding](create-onboarding).
3. Has añadido el onboarding a un [placement](placements).

El SDK de Adapty para React Native ofrece dos formas de presentar onboardings:
- **Componente React**: El componente embebido te permite integrarlo en la arquitectura y el sistema de navegación de tu app.

- **Presentación modal**
## Componente React \{#react-component\}

Para insertar un onboarding dentro de tu árbol de componentes existente, usa el componente `AdaptyOnboardingView` directamente en la jerarquía de componentes de React Native. El componente embebido te permite integrarlo en la arquitectura y el sistema de navegación de tu app.

:::note
En Android, recomendamos configuración adicional para `AdaptyOnboardingView` para evitar un artefacto visual de renderizado. Consulta [La interfaz del sistema se superpone al contenido del onboarding en Android](#system-ui-overlaps-onboarding-content-on-android).
:::
<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK versión 3.14 o posterior" default>
```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="old" label="Versión de SDK < 3.14" default>
```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  return (
    <AdaptyOnboardingView
      onboarding={onboarding}
      style={{ flex: 1 }}
      eventHandlers={{
        onAnalytics(event, meta) { 
          // Handle analytics events
        },
        onClose(actionId, meta) { 
          // Handle close actions
        },
        onCustom(actionId, meta) { 
          // Handle custom actions
        },
        onPaywall(actionId, meta) { 
          // Handle paywall actions
        },
        onStateUpdated(action, meta) { 
          // Handle state updates
        },
        onFinishedLoading(meta) { 
          // Handle when onboarding finishes loading
        },
        onError(error) { 
          // Handle errors
        },
      }}
    />
  );
}
```
</TabItem>
</Tabs>
## Presentación modal \{#modal-presentation\}

Para mostrar un onboarding como pantalla independiente que los usuarios puedan cerrar, usa el método `view.present()` en el `view` creado por el método `createOnboardingView`. Cada `view` solo puede usarse una vez. Si necesitas mostrar el onboarding de nuevo, llama a `createOnboardingView` otra vez para crear una nueva instancia de `view`.

:::warning
Reutilizar el mismo `view` sin recrearlo está prohibido. Provocará un error `AdaptyUIError.viewAlreadyPresented`.
:::
<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK version 3.14 or later" default>
```typescript showLineNumbers title="React Native (TSX)"

const view = await createOnboardingView(onboarding);

// Optional: handle onboarding events (close, custom actions, etc)
// view.setEventHandlers({ ... });

try {
    await view.present();
} catch (error) {
    // handle the error
}
```
</TabItem>
<TabItem value="old" label="SDK version < 3.14" default>
```typescript showLineNumbers title="React Native (TSX)"

const view = await createOnboardingView(onboarding);

view.setEventHandlers(); // handle close press, etc

try {
    await view.present();
} catch (error) {
    // handle the error
}
```
</TabItem>
</Tabs>
### Configurar el estilo de presentación en iOS \{#configure-ios-presentation-style\}

Configura cómo se presenta el onboarding en iOS pasando el parámetro `iosPresentationStyle` al método `present()`. El parámetro acepta los valores `'full_screen'` (predeterminado) o `'page_sheet'`.

```typescript showLineNumbers
try {
  await view.present({ iosPresentationStyle: 'page_sheet' });
} catch (error) {
  // handle the error
}
```
## Loader durante el onboarding \{#loader-during-onboarding\}

Al mostrar un onboarding en React Native, puede que notes un breve destello blanco o pantalla de carga antes de que aparezca el onboarding. Esto ocurre mientras se inicializa la vista nativa subyacente. Puedes manejarlo de distintas formas según tus necesidades y tu flujo de trabajo.

#### Controla la splash screen usando onFinishedLoading \{#control-splash-screen-using-onfinishedloading\}

:::note
Este enfoque solo está disponible al usar el componente React. No está disponible para la presentación modal.
:::
La forma recomendada en React Native es mantener visible tu pantalla de splash o un overlay personalizado hasta que el onboarding se haya cargado completamente, y luego ocultarlo manualmente.

Al usar el componente React (`AdaptyOnboardingView`), espera el evento `onFinishedLoading` antes de ocultar tu pantalla de splash o overlay:

<Tabs groupId="version" queryString>
<TabItem value="new" label="SDK versión 3.14 o posterior" default>
```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const [isLoading, setIsLoading] = useState(true);

  const onFinishedLoading = useCallback<OnboardingEventHandlers['onFinishedLoading']>((meta) => {
    // Hide your splash screen or custom overlay here
    setIsLoading(false);
  }, []);

  return (
    <>
      <AdaptyOnboardingView
        onboarding={onboarding}
        onFinishedLoading={onFinishedLoading}
        // ... other callbacks
      />
      {isLoading && <YourCustomLoadingOverlay />}
    </>
  );
}
```

</TabItem>

<TabItem value="old" label="Versión SDK < 3.14">
```typescript showLineNumbers title="React Native (TSX)"

function MyOnboarding({ onboarding }) {
  const [isLoading, setIsLoading] = useState(true);

  return (
    <>
      <AdaptyOnboardingView
        onboarding={onboarding}
        eventHandlers={{
          onFinishedLoading(meta) {
            // Hide your splash screen or custom overlay here
            setIsLoading(false);
          },
          // ... other handlers
        }}
      />
      {isLoading && <YourCustomLoadingOverlay />}
    </>
  );
}
```

</TabItem>
</Tabs>

#### Personalizar el loader nativo \{#customize-native-loader\}

:::important
El flujo gestionado de Expo no admite la colocación de layouts nativos personalizados (p. ej., `res/layout` en Android). Para aplicaciones Expo, la única solución viable es controlar la splash screen o usar un overlay de React Native.
:::

Puedes reemplazar el loader nativo usando layouts específicos de plataforma en Android e iOS. Si usas presentación modal, esta es tu única opción.

Sin embargo, este enfoque suele ser menos cómodo para aplicaciones React Native:

- Requiere implementaciones separadas para Android e iOS
- No es compatible con el flujo gestionado de Expo
Define un placeholder para cada plataforma:

- **iOS**: Añade `AdaptyOnboardingPlaceholderView.xib` a tu proyecto Xcode. [Más información](ios-present-onboardings#add-smooth-transitions-between-the-splash-screen-and-onboarding).
- **Android**: Crea `adapty_onboarding_placeholder_view.xml` en `res/layout` y define allí el placeholder. [Más información](android-present-onboardings#add-smooth-transitions-between-the-splash-screen-and-onboarding).
## Personalizar cómo se abren los enlaces en los onboardings \{#customize-how-links-open-in-onboardings\}

:::important
La personalización de cómo se abren los enlaces en los onboardings está disponible a partir de Adapty SDK v3.15.1.
:::

Por defecto, los enlaces en los onboardings se abren en un navegador integrado en la app. Esto proporciona una experiencia fluida al mostrar las páginas web dentro de tu aplicación, sin que el usuario tenga que cambiar de app.

Si prefieres abrir los enlaces en un navegador externo, puedes personalizar este comportamiento estableciendo el parámetro `externalUrlsPresentation` en `WebPresentation.BrowserOutApp`:
<Tabs groupId="rn-onboarding-views" queryString>
<TabItem value="component" label="Componente de React" default>
```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}
      externalUrlsPresentation={WebPresentation.BrowserOutApp} // default – BrowserInApp
      onAnalytics={onAnalytics}
      onClose={onClose}
      onCustom={onCustom}
      onPaywall={onPaywall}
      onStateUpdated={onStateUpdated}
      onFinishedLoading={onFinishedLoading}
      onError={onError}
    />
  );
}
```
</TabItem>
<TabItem value="modal" label="Presentación modal">

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

const view = await createOnboardingView(
  onboarding, 
  { externalUrlsPresentation: WebPresentation.BrowserOutApp } // default – BrowserInApp
);

try {
    await view.present();
} catch (error) {
    // handle the error
}
```
</TabItem>
</Tabs>
## Solución de problemas \{#troubleshooting\}

### La interfaz de sistema se superpone al contenido del onboarding en Android \{#system-ui-overlaps-onboarding-content-on-android\}

:::note
Esta configuración solo está disponible en proyectos de React Native sin Expo (bare).

Si usas el flujo de trabajo gestionado de Expo (managed workflow), no puedes añadir este recurso de Android directamente. Para aplicar esta configuración, debes crear un plugin de configuración personalizado de Expo que añada el recurso de Android correspondiente y registrarlo en `app.config.js`. Esto es necesario porque Expo gestiona el proyecto nativo de Android por ti.
:::
Al usar `AdaptyOnboardingView` en Android, los elementos de la interfaz del sistema como la barra de estado y la barra de navegación pueden aparecer sobre el contenido del paywall. Para evitarlo, añade el siguiente recurso booleano a tu app:

1. Ve a `android/app/src/main/res/values`. Si no existe el archivo `bools.xml`, créalo.

2. Añade el siguiente recurso:

```xml
<resources>
    <bool name="adapty_onboarding_enable_safe_area_paddings">false</bool>
</resources>
```

Ten en cuenta que los cambios se aplican globalmente a todos los onboardings de tu app.
## Siguientes pasos \{#next-steps\}

Una vez que hayas presentado tu onboarding, querrás [gestionar las interacciones y eventos del usuario](react-native-handling-onboarding-events). Aprende a manejar los eventos del onboarding para responder a las acciones del usuario y realizar un seguimiento de la analítica.