import { Toast, ToastConfig } from '@/utils/toast.utils'; import React, { createContext, useContext, useMemo } from 'react'; import { Alert, Platform } from 'react-native'; export interface ToastContextType { showToast: (config: ToastConfig) => void; showSuccess: (message: string, duration?: number) => void; showError: (message: string, duration?: number) => void; showWarning: (message: string, duration?: number) => void; } const ToastContext = createContext(undefined); export function ToastProvider({ children }: { children: React.ReactNode }) { const value = useMemo( () => ({ showToast: (config: ToastConfig) => { try { Toast.show(config); } catch (error) { console.error('Toast.show failed:', error); // 错误边界:在原生模块失败时提供回退方案 handleToastFallback(config.message || config.text1 || '提示', config.type); } }, showSuccess: (message: string, duration?: number) => { try { Toast.success(message, duration); } catch (error) { console.error('Toast.success failed:', error); handleToastFallback(message, 'success'); } }, showError: (message: string, duration?: number) => { try { Toast.error(message, duration); } catch (error) { console.error('Toast.error failed:', error); handleToastFallback(message, 'error'); } }, showWarning: (message: string, duration?: number) => { try { Toast.warning(message, duration); } catch (error) { console.error('Toast.warning failed:', error); handleToastFallback(message, 'warning'); } }, }), [] ); return ( {children} ); } /** * 错误边界处理:在原生 Toast 模块失败时提供回退方案 */ function handleToastFallback(message: string, type?: string) { if (!message) return; // 在 iOS 上使用 Alert 作为回退方案,避免过度打扰用户 if (Platform.OS === 'ios') { // 只对错误和警告类型使用 Alert,其他类型仅记录到控制台 if (type === 'error' || type === 'warning') { Alert.alert('', message, [{ text: '确定', style: 'default' }]); } else { console.log(`Toast (${type}): ${message}`); } } else { // 其他平台仅记录到控制台 console.log(`Toast (${type}): ${message}`); } } export function useToast(): ToastContextType { const context = useContext(ToastContext); if (context === undefined) { throw new Error('useToast must be used within a ToastProvider'); } return context; }