react-native-paper-alerts icon indicating copy to clipboard operation
react-native-paper-alerts copied to clipboard

"useAlerts must be used within a AlertsProvider" when trying to call useAlerts() in App.js

Open FloppiTuna opened this issue 3 years ago • 1 comments

Hello! I am trying to make it so an error dialog can be shown when Sentry catches an error.

Here is my code:

// imports, localization things above, unrelated to issue

const routingInstrumentation = new Sentry.Native.ReactNavigationInstrumentation(); // Create a navigation instrumentation for Sentry.

// Before rendering any navigation stack
enableScreens();

const App = ({ exp }) => {
  const navigationRef = useRef(); // Reference for the navigation container
  const alerts = useAlerts(); // This is what is causing the error
  const [isLoadingComplete, setLoading] = useState(false);

  let [fontsLoaded] = useFonts({
    'ArgonExtra': require('./assets/font/argon.ttf'),
  });

  // Initialize Sentry.
  Sentry.init({
    dsn: '...',
    integrations: [
      new Sentry.Native.ReactNativeTracing({
        tracingOrigins: ["localhost", /^\//],
        routingInstrumentation
      })
    ],
    tracesSampleRate: 0.2, // CHANGE THIS IN PRODUCTION!
    enableInExpoDevelopment: false,
    enableAutoSessionTracking: true,
    debug: true,
    beforeSend(event, hint) {
      // In the future, we can show an error report dialog on an error event.
      if (event.exception) {
        showMessage({
          message: i18n.t('Errors.InternalErrorTitle'),
          description: i18n.t('Errors.InternalErrorSubtitle'),
          onPress: () => {alerts.alert('Error', 'blah blah...')}
          type: 'danger',
          icon: 'danger',
        })
      }
      return event;
    },
  });
  function _handleLoadingError(error) {
    // Send loading errors to Sentry.
    Sentry.Native.captureException(error);
  };

  function _handleFinishLoading() {
    // Tell the app to switch from AppLoading to the NavigationContainer (our app).
    setLoading(true);
  };

  if (!fontsLoaded && !isLoadingComplete) {
    return (
      <AppLoading
        onError={_handleLoadingError}
        onFinish={_handleFinishLoading}
      />
    );
  } else if (fontsLoaded) {
    return (
      <NavigationContainer
        ref={navigationRef}
        onReady={() => {
          // Register the navigation container with the instrumentation
          routingInstrumentation.registerNavigationContainer(navigationRef);
        }}>
        <PaperProvider theme={theme}>
          <AlertsProvider>
            <RecoilRoot>
              <GalioProvider theme={argonTheme}>
                <Block flex>
                  <Screens />
                  <FlashMessage position='bottom' />
                </Block>
              </GalioProvider>
            </RecoilRoot>
          </AlertsProvider>
        </PaperProvider>
      </NavigationContainer>
    );
  } else {
    return null
  }
}

export default Sentry.Native.wrap(App);

Is there any way to call useAlerts within the main file (index.js, App.js, etc...), or will I need to take a different route? Also, apologizes if I've provided not enough information, i'll happily provide any needed. 😅

FloppiTuna avatar Aug 14 '22 03:08 FloppiTuna

Hi, sorry I completely missed this one. AS the error states, the useAlerts hook must be called inside AlertsProvider. I'm not sure if it's possible here to create a Main component of some sorts that provides the PaperProvider and AlertsProvider, and then render the App component inside. This would generally work but I'm not sure if the Sentry wrapper must be top level.

Cheers.

kuasha420 avatar Sep 16 '24 08:09 kuasha420