calintamas / react-native-toast-message

Animated toast message component for React Native
MIT License
1.72k stars 264 forks source link

Doesnt work with react-navigation/native #195

Closed activebiz closed 2 years ago

activebiz commented 3 years ago

The toaster doesnt appear when using @react-navigation/native lib. Have followed as shown in https://github.com/calintamas/react-native-toast-message#how-to-render-the-toast-when-using-react-navigation

I have placed <Toast/ > as last element inside <NavigationContainer>....</NavigationContainer>.

Any one else having same issue?

lucswart commented 3 years ago

Yep, having the same issue! What you could do for now is to place it on the screen itself. Not the nicest way of implementing, but that is what I do for now.

Skkay commented 3 years ago

Works perfectly for me on Android using Expo with:

PopBot commented 3 years ago

Are you all on Expo? I'm running on Expo and having issues as well with React Native Navigation.

ronmara commented 3 years ago

Could you post your code?

Skkay commented 3 years ago

In my App.js:

...
import Toast from 'react-native-toast-message'
...
const App = () => {
  ...
  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        {isConnected ? (
          <Drawer.Navigator initialRouteName="Home" drawerContent={props => (
            <CustomDrawer props={props} signOut={signOut} />
          )} >
            <Drawer.Screen name="Home" component={MainStackNavigator} options={{ title: "Accueil" }} />
            <Drawer.Screen name="MyOrders" component={MyOrdersStackNavigator} options={{ title: "Mes commandes" }} />
            <Drawer.Screen name="MyReservations" component={MyReservationsStackNavigator} options={{ title: "Mes réservations" }} />
          </Drawer.Navigator>
        ) : (
          <Stack.Navigator initialRouteName="Login">
            <Stack.Screen name="Login" options={{ title: "Connexion" }}>
              {({ navigation }) => <LoginScreen navigation={navigation} setConnected={setConnected} />}
            </Stack.Screen>
            <Stack.Screen name="Register" component={RegisterScreen} options={{ title: "Inscription" }} />
          </Stack.Navigator>
        )}
        <Toast ref={(ref) => Toast.setRef(ref)} />
      </NavigationContainer>
    </AuthContext.Provider>
  );
};

And in my HomeScreen.js I call my Toast like that:

...
import Toast from 'react-native-toast-message'
...
const HomeScreen = ({ route, navigation }) => {
  const { toastType, toastExtra } = route.params;

  // Toast notifications
  useEffect(() => {
    if (toastType === "order_success_takeout") {
      Toast.show({
        text1: `Commande n°${toastExtra.id}`,
        text2: 'Votre commande à emporter a été envoyée avec succès.'
      });
    }
    if (toastType === "order_success_eatin") {
      Toast.show({
        text1: `Commande n°${toastExtra.id}`,
        text2: 'Votre commande sur place a été envoyée avec succès.'
      });
    }
    if (toastType === "reservation_success") {
      const date = new Date(toastExtra.date);
      Toast.show({
        text1: 'Réservation confirmée',
        text2: `Réservation d'une table de ${toastExtra.table_.place} ${toastExtra.table_.place > 1 ? "places" : "place" }, pour le service de ${toastExtra.service.startTime}h-${toastExtra.service.endTime}h le ${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getFullYear()}.`
      });
    }
  });

  return (
    ...
  );
};

Exactly as explained here https://github.com/calintamas/react-native-toast-message#how-to-render-the-toast-when-using-react-navigation and I have no problem

charlotteisambert commented 3 years ago

I don't know if this may help, but it didn't work for me because I placed the Toast element above my screens. Make sure you placed the<Toast ref={(ref) => Toast.setRef(ref)} /> after all of your screens:

<NavigationContainer>
      {...}
      <Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>

and not

<NavigationContainer>
      <Toast ref={(ref) => Toast.setRef(ref)} />
      {...}
</NavigationContainer>
lucswart commented 3 years ago

@charlotteisambert This did actually help! Woah, thank you.. It works perfectly now.

anoop0567 commented 3 years ago

maybe this can help, I just removed React.useEffect and it's worked

React.useEffect(() => {
    Toast.show({
      text1: 'Hello',
      text2: 'This is some something 👋'
    });
}, []);

changed to

Toast.show({
    text1: 'Hello',
    text2: 'This is some something 👋'
});

I was getting this error before

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue
PopBot commented 3 years ago

I can verify, placing Toast after screens works for me!

shlok-ps commented 3 years ago

I don't know if this may help, but it didn't work for me because I placed the Toast element above my screens. Make sure you placed the<Toast ref={(ref) => Toast.setRef(ref)} /> after all of your screens:

<NavigationContainer>
      {...}
      <Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>

and not

<NavigationContainer>
      <Toast ref={(ref) => Toast.setRef(ref)} />
      {...}
</NavigationContainer>

I can use Toast inside navigation with this. But not outside of it. Is there a way to run it both inside and outside of Navigation Container.

calintamas commented 3 years ago

@shlok-ps yes, you can render it alongside RootNavigator, like so

function App() {
  return (
    <>
      <RootNavigator />
      <Toast ref={(ref) => Toast.setRef(ref)} />
    </>
  )
}
MorenoMdz commented 3 years ago

I don't know if this may help, but it didn't work for me because I placed the Toast element above my screens. Make sure you placed the<Toast ref={(ref) => Toast.setRef(ref)} /> after all of your screens:

<NavigationContainer>
      {...}
      <Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>

and not

<NavigationContainer>
      <Toast ref={(ref) => Toast.setRef(ref)} />
      {...}
</NavigationContainer>

This is actually the solution, if someone has time please add this as a note to the repo readme.md ;)

calintamas commented 3 years ago

Updated the phrasing in the readme, commit https://github.com/calintamas/react-native-toast-message/commit/1b5d936b04dc66109ece21d0cf5c22d2dcb0a1e3. I think it should be fine now.

AdriaRios commented 3 years ago

Hey @calintamas !

When we use a modal navigation, the toast appears below the view. We are following your recommendation, no luck.

Any idea? Thank you!

EDIT

Ok, I found why and maybe this could help to more people. To get the toast correctly working when you are using modals to navigate, the presentation prop must be:

If you use another type (modal, fullScreenModal or transparentModal), iOS will place the new modal above everything, including your awesome toast.

rush86999 commented 3 years ago

can confirm the toast is hidden behind status bar using the recommended approach. It is also visible for some reason instead of being hidden. This is a bare react native with expo unimodules and react navigation.

Screen Shot 2021-08-20 at 10 26 09 AM

EDIT: Can confirm it works by putting it under the root navigation component (in the bottom) instead of the container from the initial entry at App.tsx

return (
    <SafeAreaView style={styles.container}>
      <StatusBar />
          <UserNavigation />
      <Toast ref={(ref) => Toast.setRef(ref)} />
  </SafeAreaView>
  )
calintamas commented 3 years ago

Make sure to render the Toast outside the SafeAreaView component.

In your case,

  return (
    <>
      <SafeAreaView style={styles.container}>
        <StatusBar />
        <UserNavigation />
      </SafeAreaView>
      <Toast ref={(ref) => Toast.setRef(ref)} />  {/* ref is not needed when using v2 /*}
    </>
  );
calintamas commented 2 years ago

Closing as the docs have been updated for v2. If there are any other issues, feel free to re-open

dsws commented 2 years ago

I don't know if this may help, but it didn't work for me because I placed the Toast element above my screens. Make sure you placed the<Toast ref={(ref) => Toast.setRef(ref)} /> after all of your screens:

<NavigationContainer>
      {...}
      <Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>

and not

<NavigationContainer>
      <Toast ref={(ref) => Toast.setRef(ref)} />
      {...}
</NavigationContainer>

Thank you!

joerush18 commented 1 year ago

I don't know if this may help, but it didn't work for me because I placed the Toast element above my screens. Make sure you placed the<Toast ref={(ref) => Toast.setRef(ref)} /> after all of your screens:

<NavigationContainer>
      {...}
      <Toast ref={(ref) => Toast.setRef(ref)} />
</NavigationContainer>

and not

<NavigationContainer>
      <Toast ref={(ref) => Toast.setRef(ref)} />
      {...}
</NavigationContainer>

This worked for me.