Skip to content

Implementing TourGuideZone on Top Navbar leads to "Maximum update depth exceeded" error #159

Open
@AbisheekKumar

Description

@AbisheekKumar

Hi, I’m using React Native Expo and trying to guide users through the menus in the app’s top navigation bar. However, when implementing Tour Zone within the top navigation bar, I’m encountering a "Maximum update depth exceeded" error, and the app crashes. Interestingly, implementing the same functionality outside the top navigation bar works perfectly. How can I resolve this issue?

App.js:

import React, { useEffect, useState, useCallback, useContext } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Provider } from 'react-redux';
import { store } from './store';
import { RealmCustomProvider } from './providers/Realm';
import * as SplashScreen from 'expo-splash-screen';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { ApplicationProvider, IconRegistry } from '@ui-kitten/components';
import * as eva from '@eva-design/eva';
import { EvaIconsPack } from '@ui-kitten/eva-icons';
import ThemeContextProvider, { ThemeContext } from './theme-context';
import { lightTheme, darkTheme } from './components/common/DatePickerTheme'; // Remove if unused
import { default as themes } from './theme_config/themes.json';
import Navigation from './routes/Navigation';
import { TourGuideProvider } from 'rn-tourguide';

SplashScreen.preventAutoHideAsync();

const App = () => {
  const [appIsReady, setAppIsReady] = useState(false);
  const { theme } = useContext(ThemeContext);

  // Simulate splash screen display
  useEffect(() => {
    const prepareApp = async () => {
      try {
        await new Promise((resolve) => setTimeout(resolve, 2000));
      } finally {
        setAppIsReady(true);
      }
    };
    prepareApp();
  }, []);

  // Hide splash screen when the app is ready
  const onLayoutRootView = useCallback(async () => {
    if (appIsReady) {
      await SplashScreen.hideAsync();
    }
  }, [appIsReady]);

  if (!appIsReady) {
    return null; // Show nothing while the splash screen is displayed
  }

  return (
    <TourGuideProvider preventOutsideInteraction androidStatusBarVisible={true}>
      <SafeAreaView style={{ flex: 1 }} onLayout={onLayoutRootView}>
        <Provider store={store}>
          <ThemeContextProvider>
            <IconRegistry icons={EvaIconsPack} />
            <ApplicationProvider
              {...eva}
              theme={{ ...eva[theme], ...themes }}
              customMapping={colorMapping} // Ensure `colorMapping` is defined
            >
              <Navigation />
            </ApplicationProvider>
          </ThemeContextProvider>
        </Provider>
      </SafeAreaView>
    </TourGuideProvider>
  );
};

export default App;


HomePage.js:

import React, { useEffect, useRef, useContext } from 'react';
import { ScrollView, StatusBar, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useNavigation } from '@react-navigation/native';
import { DrawerActions } from '@react-navigation/native';
import { TopNavigation, TopNavigationAction, Layout } from '@ui-kitten/components';
import { useDispatch } from 'react-redux';
import { useTourGuideController, TourGuideZone } from 'rn-tourguide';
import CustomTextComponent from '../components/common/CustomTextComponent';
import GreetingsContainer from '../components/GreetingsContainer';
import { useTheme } from '../theme/themeContext'; // Adjust if custom hook is used
import HomePageStyles from '../styles/HomePageStyles'; // Replace with the correct path

const HomeScreen = () => {
    const globalTheme = useTheme();
    const { theme } = useContext(ThemeContext);
    const navigation = useNavigation();
    const dispatch = useDispatch();
    const { canStart, start, stop, eventEmitter } = useTourGuideController();

    const handleOnStart = () => console.log('Tour started');
    const handleOnStop = () => console.log('Tour stopped');
    const handleOnStepChange = (step) => console.log(`Step changed: ${step}`);

    // Automatically start the tour if it's ready
    useEffect(() => {
        if (canStart) {
            console.log("Guided Tour is starting...");
            start();
        }
    }, [canStart]);

    // Register event listeners for the tour
    useEffect(() => {
        eventEmitter.on('start', handleOnStart);
        eventEmitter.on('stop', handleOnStop);
        eventEmitter.on('stepChange', handleOnStepChange);

        return () => {
            eventEmitter.off('start', handleOnStart);
            eventEmitter.off('stop', handleOnStop);
            eventEmitter.off('stepChange', handleOnStepChange);
        };
    }, []);

    // Render the drawer action with a tour zone
    const renderDrawerAction = () => (
        <TourGuideZone
            zone={1}
            shape="circle"
            text="Tap here to explore the menu"
        >
            <TopNavigationAction
                icon={<EvaIcons name="menu-2-outline" fill="white" />}
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
            />
        </TourGuideZone>
    );

    return (
        <SafeAreaView style={{ flex: 1 }}>
            <StatusBar backgroundColor={globalTheme['color-primary-default']} />
            <TopNavigation
                title={() => (
                    <CustomTextComponent
                        category="h6"
                        styles={{ color: 'white', fontFamily: 'heading-font' }}
                        textContent="FINGURU"
                    />
                )}
                subtitle={() => (
                    <CustomTextComponent
                        category="s2"
                        styles={{ color: 'white', fontFamily: 'heading-font' }}
                        textContent="Your Financial Advisor"
                    />
                )}
                alignment="center"
                accessoryLeft={renderDrawerAction}
                style={{ backgroundColor: globalTheme['color-primary-default'] }}
            />
            <Layout style={{ flex: 1, backgroundColor: theme.background }} level="3">
                <ScrollView showsVerticalScrollIndicator={false}>
                    <View style={HomePageStyles.greetingsContainer}>
                        <TourGuideZone
                            zone={2}
                            shape="rectangle"
                            text="This is the greetings section"
                        >
                            <GreetingsContainer />
                        </TourGuideZone>
                    </View>
                </ScrollView>
            </Layout>
        </SafeAreaView>
    );
};

export default HomeScreen;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions