react-nativereact-hookstoast

toast.show() function is not working when the app starts


While I am using react-native-toast-notifications in my react native project, I have used useToast() in my splash screen.

I have wrapped splash screen component using ToastProvider

Here it is.

import { DefaultTheme, NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { SplashScreen } from '@pages/auth/splash'
import { SignIn } from '@pages/auth/login'
import { ToastProvider } from 'react-native-toast-notifications'

const RootStack = createNativeStackNavigator()
const navigationContainerTheme = DefaultTheme
navigationContainerTheme.colors.background = color.appBackgroudColor

export const Routing = () => {
    return (
        <ToastProvider>
            <MenuProvider>
                <NavigationContainer theme={navigationContainerTheme}>
                    <RootStack.Navigator
                        initialRouteName={Routes.SPLASH}
                        screenOptions={{ animation: 'none' }}
                    >
                        <RootStack.Screen
                            name={Routes.SIGN_IN}
                            component={SignIn}
                            options={{
                                headerShown: false,
                            }}
                        />
                        ...
                    </RootStack.Navigator>
                </NavigationContainer>
            </MenuProvider>
        </ToastProvider>
    )
}

And here is my splashscreen.ts file

import React, { useEffect } from 'react'
import {
    ScrollView,
    StyleSheet,
    useColorScheme,
    View,
    TouchableOpacity,
} from 'react-native'
import { SplashScreenProps } from '@app/types'
import { Routes } from '@shared/config/routes'
import { sendPing } from '@shared/api/defaultApi'
import { useToast } from 'react-native-toast-notifications'

export const SplashScreen = ({ navigation }: SplashScreenProps) => {
    const css = styleInit(useColorScheme() === 'dark')
    const toast = useToast()

    useEffect(() => {
        showSplashScreen()
    }, [navigation])

    const showSplashScreen = async () => {
        const pingResponse = await sendPing()
        if (pingResponse) {
            toast.show('Success to connect server!')
            navigation.navigate(Routes.AUTHORIZE)
        } else {
            toast.show('Failed to connect server!')
            console.log('Ping server failed!')
        }
    }

    return (
        <View>
            <Text>Splashscreen</Text>
        </View>
    )
}

And if i start the app, it will send a ping to server and get the response. And after i get the response, this error has occurred

Possible unhandled promise rejection (id: 0: TypeError: toast.show is not a function (it is undefined)
...

I dont know what the reason is, maybe there is delay to initialize the toast using useToast() hook? I would appreciate it if someone could help me with this problem. Thanks.

I have tried to set the timeout till the toast is initialized, but it didnt work as well.


Solution

  • You should wait until Toast component is rendered, which can be done using useEffect.

    useEffect(() => {
        const initializeToast = async () => {
            while (!toast || !toast.show) {
                await new Promise(resolve => setTimeout(resolve, 100))
            }
            isToastInitialized.current = true
            showSplashScreen()
        }
        initializeToast()
    }, [toast])