Toast
Notifications toast et alertes sur mobile avec Alert.alert() et composants toast personnalisés.
Toast
Les applications mobiles ont besoin de retour pour les actions utilisateur. ScaleRocket Mobile supporte les alertes natives et les notifications toast personnalisées.
Alerte native
L'approche la plus simple est l'Alert.alert() intégré de React Native :
import { Alert } from "react-native";
// Alerte simple
Alert.alert("Success", "Your profile has been updated.");
// Alerte avec actions
Alert.alert(
"Delete Account",
"Are you sure? This action cannot be undone.",
[
{ text: "Cancel", style: "cancel" },
{ text: "Delete", style: "destructive", onPress: handleDelete },
]
);| Plateforme | Comportement |
|---|---|
| iOS | Dialogue modal natif |
| Android | Dialogue Material |
Quand utiliser Alert vs Toast
| Scénario | Utiliser |
|---|---|
| Confirmation destructive | Alert.alert() avec actions |
| Retour de succès | Toast |
| Message d'erreur | Toast (non-bloquant) ou Alert (critique) |
| Erreur réseau | Toast avec action de réessai |
| Validation de formulaire | Erreurs en ligne (pas toast) |
Composant Toast personnalisé
Pour les notifications non-bloquantes, utilisez un toast personnalisé :
import { useRef } from "react";
import { Animated, Text, StyleSheet } from "react-native";
interface ToastProps {
message: string;
type?: "success" | "error" | "info";
}
function Toast({ message, type = "info" }: ToastProps) {
const opacity = useRef(new Animated.Value(0)).current;
const show = () => {
Animated.sequence([
Animated.timing(opacity, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.delay(2000),
Animated.timing(opacity, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}),
]).start();
};
const colors = {
success: "#10B981",
error: "#EF4444",
info: "#3B82F6",
};
return (
<Animated.View
style={[styles.toast, { opacity, backgroundColor: colors[type] }]}
>
<Text style={styles.text}>{message}</Text>
</Animated.View>
);
}
const styles = StyleSheet.create({
toast: {
position: "absolute",
top: 60,
left: 16,
right: 16,
padding: 16,
borderRadius: 12,
zIndex: 1000,
},
text: { color: "white", fontWeight: "600", textAlign: "center" },
});Contexte Toast
Créez un contexte pour que n'importe quel écran puisse déclencher un toast :
import { createContext, useContext, useState, useCallback } from "react";
const ToastContext = createContext<{
show: (message: string, type?: "success" | "error" | "info") => void;
} | null>(null);
export function ToastProvider({ children }: { children: React.ReactNode }) {
const [toast, setToast] = useState<ToastProps | null>(null);
const show = useCallback((message: string, type: "success" | "error" | "info" = "info") => {
setToast({ message, type });
setTimeout(() => setToast(null), 3000);
}, []);
return (
<ToastContext.Provider value={{ show }}>
{children}
{toast && <Toast message={toast.message} type={toast.type} />}
</ToastContext.Provider>
);
}
export const useToast = () => useContext(ToastContext)!;Utilisation depuis n'importe quel écran :
function ProfileScreen() {
const toast = useToast();
const handleSave = async () => {
try {
await saveProfile();
toast.show("Profile saved!", "success");
} catch {
toast.show("Failed to save profile", "error");
}
};
return <Button title="Save" onPress={handleSave} />;
}Configuration dans le Root Layout
Enveloppez votre app avec ToastProvider :
// app/_layout.tsx
import { ToastProvider } from "@/components/ui/Toast";
export default function RootLayout() {
return (
<ToastProvider>
<Slot />
</ToastProvider>
);
}Toast avec action
Ajoutez un bouton annuler ou réessayer :
<Animated.View style={[styles.toast, { opacity }]}>
<Text style={styles.text}>{message}</Text>
{action && (
<TouchableOpacity onPress={action.onPress}>
<Text style={styles.action}>{action.label}</Text>
</TouchableOpacity>
)}
</Animated.View>