react-native-toast-message

repository·main·Indexed 24 days ago

https://github.com/calintamas/react-native-toast-message

A lightweight (~40 kB), animated toast notification library for React Native featuring an imperative API and keyboard awareness. It supports customizable layouts, flexible configuration for success, error, and info types, and provides a Toast component for global defaults. The library includes support for custom animations via animationConfig and specific integration patterns for React Navigation, Modals, and Jest testing.

Tokens
7.1K
Snippets
20
Records
35
Agent score
79%

What's inside react-native-toast-message

  1. Overview of react-native-toast-message

    main
    react-native-toast-message is an animated toast message component for React Native. It provides an imperative API to trigger notifications, is highly lightweight (~40 kB), and is keyboard-aware. It supports customizable layouts and flexible configuration to fit various UI requirements.
  2. How Toast refs are tracked

    main

    The library uses an internal mechanism to track which <Toast /> instance should respond to imperative calls like Toast.show() or Toast.hide().

    When you render <Toast />, a ref is created and tracked automatically. If multiple <Toast /> instances exist (for example, one at the root and one inside a Modal), the library uses the ref from whichever instance was last mounted or had its ref set. This allows seamless switching between the root toast and a modal-specific toast as components mount and unmount.

    // App.jsx
    import Toast from 'react-native-toast-message'
    
    export function App(props) {
      return (
        <>
          {/* A `ref` pointing to this Toast instance is created and tracked internally */}
          <Toast />
        </>
      );
    }
  3. Showing Toasts with react-native-modal or NativeStackNavigator

    main

    The requirement to render a <Toast /> instance inside the presenting layer applies to react-native-modal and NativeStackNavigator screens using presentation: 'modal'.

    To ensure toasts are visible during these presentations, nest a <Toast /> component within the modal or the specific stack screen. The library will automatically use the most recently mounted instance.

    <>
      {/* This `Toast` will show when neither the native stack screen nor `Modal` are presented */}
      <Toast />
    
      <NativeStackNavigator.Screen>
        {/* This `Toast` will show when the `NativeStackNavigator.Screen` is visible, but the `Modal` is NOT visible. */}
        <Toast />
    
        <Modal>
          {/* This `Toast` will show when both the `NativeStackNavigator.Screen` and the `Modal` are visible. */}
          <Toast />
        </Modal>
      </NativeStackNavigator.Screen>
    </>
  4. Mock the library for testing with Jest

    main

    To prevent actual toast notifications from appearing during your Jest tests and to allow you to assert that toast methods were called, you can mock the react-native-toast-message module. Use jest.mock to provide mock implementations for the show and hide functions.

    jest.mock('react-native-toast-message', () => ({
      show: jest.fn(),
      hide: jest.fn()
    }));
  5. Create custom toast layouts and types

    main

    You can customize existing toast types or create entirely new ones by providing a config object to the Toast component at your app's entry point.

    There are two ways to create a custom layout:

    1. Modify existing types: Use the built-in BaseToast, SuccessToast, ErrorToast, or InfoToast components and pass them custom styles via props.
    2. Build from scratch: Create a new component function that receives text1, text2, and props. Any custom data passed to the props key in the Toast.show() method will be available in this object.

    To use a custom type, ensure the key in your toastConfig object matches the type string passed to Toast.show().

    // 1. Define the config
    const toastConfig = {
      // Overwriting an existing type
      success: (props) => (
        <BaseToast
          {...props}
          style={{ borderLeftColor: 'pink' }}
        />
      ),
      // Creating a completely new type
      tomatoToast: ({ text1, props }) => (
        <View style={{ height: 60, width: '100%', backgroundColor: 'tomato' }}>
          <Text>{text1}</Text>
          <Text>{props.uuid}</Text>
        </View>
      )
    };
    
    // 2. Pass config to the Toast component
    export function App() {
      return (
        <>
          {/* ... other components ... */}
          <Toast config={toastConfig} />
        </>
      );
    }
    
    // 3. Trigger the custom type
    Toast.show({
      type: 'tomatoToast',
      props: { uuid: 'bba1a7d0-6ab2-4a0a-a76e-ebbe05ae6d70' }
    });
  6. Set up the Toast component

    main

    To enable toast notifications, you must render the Toast component in your app's entry file. It should be placed as the LAST CHILD in your component hierarchy (alongside other top-level components) to ensure it renders on top of other UI elements.

    // App.jsx
    import Toast from 'react-native-toast-message';
    
    export function App(props) {
      return (
        <>
          {/* ... other components ... */}
          <Toast />
        </>
      );
    }
  7. Render Toast on top of React Navigation

    main

    When using a navigation library like react-navigation, the Toast component must be rendered as the last child in your root component's hierarchy, alongside the NavigationContainer. This ensures the Toast is visible on top of the navigation View hierarchy and is not obscured by screens or navigation elements.

    import Toast from 'react-native-toast-message'
    import { NavigationContainer } from '@react-navigation/native';
    
    export function App() {
      return (
        <>
          <NavigationContainer>
            {/* ... your navigation stack ... */}
          </NavigationContainer>
          <Toast />
        </>
      );
    }
  8. Show a Toast inside a Modal

    main

    Because React Native's Modal component renders above the root View, a <Toast /> instance placed at the app's root will be hidden behind a Modal. To show a Toast on top of a Modal, you must render a second <Toast /> instance inside the Modal component itself.

    When the Modal is visible, the library automatically uses the ref from the <Toast /> instance inside the Modal. When the Modal is closed, it reverts to using the root <Toast /> instance. You continue to use the same imperative API (Toast.show() or Toast.hide()) to trigger them.

    // App.jsx
    import { Modal } from 'react-native'
    import Toast from 'react-native-toast-message'
    
    export function App(props) {
      const [isModalVisible, setIsModalVisible] = React.useState(false);
    
      return (
        <>
          {/* Root Toast for normal app usage */}
          <Toast />
          
          <Modal visible={isModalVisible}>
            {/* Toast instance inside the Modal to ensure it appears on top */}
            <Toast />
          </Modal>
        </>
      );
    }
  9. How Toast priority works in view hierarchies

    main

    The library manages multiple Toast instances using a priority system based on mounting order. The most recently mounted Toast component (the one highest in the view hierarchy) is considered the 'active' instance.

    This is particularly useful when using Modals. If you have a Toast at the App root and another Toast inside a Modal, calling Toast.show() will target the Toast inside the Modal because it was mounted later and sits on top of the view hierarchy.

    <>
      <Toast />
      <Modal>
        <Toast />
      </Modal>
    </>
  10. Define custom toast layouts with ToastConfig

    main

    To create custom toast appearances, provide a ToastConfig object to the <Toast /> component. The keys in the object correspond to ToastType values, and the values are functions that return a React node.

    Each function receives ToastConfigParams, which provides access to the toast's state and data:

    • position: Current position.
    • type: The toast type.
    • isVisible: Boolean indicating if the toast is visible.
    • text1 / text2: The content strings.
    • show / hide: Functions to programmatically control the toast.
    • onPress: The press handler.
    • props: Custom properties passed during the .show() call.
    export type ToastConfig = {
      [key: string]: (params: ToastConfigParams<any>) => React.ReactNode;
    };
  11. Integrate the Toast component into your application

    main

    To use the library, render the Toast component at the root of your application. The Toast component is designed to be used as a singleton or within specific hierarchies (like Modals) to manage toast notifications.

    When multiple Toast components are mounted, the library uses a priority system: the component mounted last (the one highest in the view hierarchy, such as inside a Modal) takes precedence for Toast.show() and Toast.hide() calls.