Ir al contenido

React Native

El SDK incluye un renderer para React Native, pero es un stub: registra eventos del ciclo de vida y emite los eventos correctos del SDK, pero no renderiza ninguna UI por sí mismo. Para mostrar un popup en una app React Native debes aportar la capa de UI (normalmente un Modal con un WebView o con componentes nativos) y devolver al SDK las señales de finalización/cierre.

El SDK detecta RN automáticamente mediante navigator.product === 'ReactNative' y selecciona el renderer RN en ese caso. Puedes sustituirlo por uno propio con popups.setRenderer().

El SDK se apoya en la interfaz PopupRenderer:

interface PopupRenderer {
init?(): void;
show(
surveyId: string,
productId: string,
data: Record<string, unknown> | undefined,
emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void,
onClose: () => void,
): void;
hide(): void;
}

Cuando se ejecuta popups.show(...) (manualmente o por un trigger), el SDK llama a renderer.show(...) y te pasa:

  • emit — llámalo con 'survey_completed' (y opcionalmente 'popup_clicked') para devolver eventos al SDK.
  • onClose — llámalo cuando el usuario cierre el modal para que el SDK limpie su estado interno.
Ventana de terminal
npm install @magicfeedback/popup-sdk react-native-webview

La integración recomendada es un único componente React que:

  1. Mantiene el estado de la encuesta activa.
  2. Implementa PopupRenderer y se registra en el SDK con setRenderer().
  3. Renderiza un Modal con un WebView apuntando a tu encuesta MagicFeedback.
  4. Escucha mensajes del WebView y llama a emit('survey_completed', ...).
DeepdotsPopupHost.tsx
import { useEffect, useRef, useState } from 'react';
import { Modal, View, StyleSheet } from 'react-native';
import { WebView, WebViewMessageEvent } from 'react-native-webview';
import { DeepdotsPopups, DeepdotsEventType } from '@magicfeedback/popup-sdk';
type EmitFn = (
type: DeepdotsEventType,
surveyId: string,
data?: Record<string, unknown>,
) => void;
type ActiveSurvey = {
surveyId: string;
productId: string;
emit: EmitFn;
onClose: () => void;
};
export function DeepdotsPopupHost({ userId }: { userId?: string }) {
const [active, setActive] = useState<ActiveSurvey | null>(null);
const popupsRef = useRef<DeepdotsPopups | null>(null);
useEffect(() => {
const popups = new DeepdotsPopups();
popups.setRenderer({
init() {},
show(surveyId, productId, _data, emit, onClose) {
setActive({ surveyId, productId, emit, onClose });
},
hide() {
setActive(null);
},
});
popups.init({
mode: 'server',
apiKey: 'YOUR_PUBLIC_API_KEY',
userId,
});
popups.autoLaunch();
popupsRef.current = popups;
return () => {
popups.setRenderer({ show() {}, hide() {} });
};
}, [userId]);
const handleMessage = (event: WebViewMessageEvent) => {
if (!active) return;
try {
const msg = JSON.parse(event.nativeEvent.data);
if (msg.type === 'survey_completed') {
active.emit('survey_completed', active.surveyId, msg.data);
active.onClose();
setActive(null);
}
} catch {
// ignora mensajes que no sean JSON
}
};
return (
<Modal
visible={!!active}
animationType="slide"
onRequestClose={() => {
active?.onClose();
setActive(null);
}}
>
<View style={styles.container}>
{active && (
<WebView
source={{
uri: `https://app.magicfeedback.io/survey/${active.surveyId}?productId=${active.productId}`,
}}
onMessage={handleMessage}
/>
)}
</View>
</Modal>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'white' },
});

Monta el host una sola vez en la raíz de tu app:

App.tsx
import { DeepdotsPopupHost } from './DeepdotsPopupHost';
export default function App() {
return (
<>
<YourNavigation />
<DeepdotsPopupHost userId="customer-123" />
</>
);
}

Expón la instancia del SDK con un contexto o una ref y llama a show() desde cualquier sitio:

popupsRef.current?.show({
surveyId: 'survey-home-001',
productId: 'product-main',
});

Tu página de encuesta debe enviar mensajes al WebView para que el SDK registre la respuesta. Desde el HTML de la encuesta (o desde el callback de MagicFeedback):

window.ReactNativeWebView?.postMessage(
JSON.stringify({ type: 'survey_completed', data: { rating: 9 } })
);

El handler handleMessage mostrado arriba traduce eso en emit('survey_completed', ...), lo que dispara el evento survey_completed del SDK y aplica el cooldown del popup.