react-navigation-shared-element icon indicating copy to clipboard operation
react-navigation-shared-element copied to clipboard

[v5]/[v3] Maximum update depth exceeded [ in SharedElementStackNavigator (at createSharedElementStackNavigator.js:99) ]

Open ibrahimahmed-io opened this issue 4 years ago • 4 comments

I am having this error after replacing createStackNavigator with createSharedElementStackNavigator and this is the case with 5.0.0-alpha1 and v3 as well

[Thu Dec 10 2020 15:48:46.732]  ERROR    Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
    in SharedElementStackNavigator (at createSharedElementStackNavigator.js:99)
    in WrapNavigator (at navigation/index.js:69)
    in JobNavigator (at SceneView.tsx:122)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:115)
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at BottomNavigation.tsx:734)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at BottomNavigation.tsx:719)
    in RCTView (at View.js:34)
    in View (at BottomNavigation.tsx:699)
    in RCTView (at View.js:34)
    in View (at BottomNavigation.tsx:698)
    in BottomNavigation (created by Context.Consumer)
    in ThemedComponent (created by withTheme(BottomNavigation))
    in withTheme(BottomNavigation) (at MaterialBottomTabView.tsx:94)
    in MaterialBottomTabViewInner (at MaterialBottomTabView.tsx:191)
    in MaterialBottomTabView (at createMaterialBottomTabNavigator.tsx:45)
    in MaterialBottomTabNavigator (at navigation/index.js:120)
    in TabNavigator (at SceneView.tsx:122)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:115)
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:245)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:244)
    in RCTView (at View.js:34)
    in View (at CardSheet.tsx:33)
    in ForwardRef(CardSheet) (at Card.tsx:573)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:555)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Card.tsx:549)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:544)
    in RCTView (at View.js:34)
    in View (at Card.tsx:538)
    in Card (at CardContainer.tsx:206)
    in CardContainer (at CardStack.tsx:619)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:84)
    in MaybeScreen (at CardStack.tsx:612)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:54)
    in MaybeScreenContainer (at CardStack.tsx:494)
    in CardStack (at StackView.tsx:462)
    in KeyboardManager (at StackView.tsx:458)
    in RNCSafeAreaProvider (at SafeAreaContext.tsx:74)
    in SafeAreaProvider (at SafeAreaProviderCompat.tsx:42)
    in SafeAreaProviderCompat (at StackView.tsx:455)
    in GestureHandlerRootView (at GestureHandlerRootView.android.js:31)
    in GestureHandlerRootView (at StackView.tsx:454)
    in StackView (at createStackNavigator.tsx:87)
    in StackNavigator (at navigation/index.js:289)
    in MainNavigator (at App.js:100)
    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
    in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:91)
    in ThemeProvider (at NavigationContainer.tsx:90)
    in ForwardRef(NavigationContainer) (at App.js:99)
    in ThemeProvider (at Portal.tsx:54)
    in RCTView (at View.js:34)
    in View (at PortalManager.tsx:42)
    in PortalManager (at PortalHost.tsx:133)
    in Portal.Host (at Provider.tsx:81)
    in Provider (at App.js:97)
    in Provider (at App.js:96)
    in App (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)

Navigation Code

import React from 'react';

import { createStackNavigator } from '@react-navigation/stack';

import { createSharedElementStackNavigator } from 'react-navigation-shared-element';

import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';

import { View, Dimensions, Image } from 'react-native';

import { IconButton, Appbar, Text, Badge } from 'react-native-paper';

import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

import Constants from 'expo-constants';

import Login from 'screens/login';
import Register from 'screens/register';
import Register2 from 'screens/register-2';
import Register3 from 'screens/register-3';
import PreLoader from 'screens/preloader';
import GetStarted from 'screens/get-started';

import JobList from 'screens/jobs/job-list';
import JobDetails from 'screens/jobs/job-details';
import EmptyScreen from 'screens/empty';

import TabBar from 'components/MaterialTopTabBar';
import TabBarLabel from 'components/TabBarLabel';

let _navigator;

const images = {
    logo: require('MonaseqInfluencer/assets/logo-small.png'),
    logoMini: require('MonaseqInfluencer/assets/logo-mini.png'),
};

function JobNavigator() {
    const Stack = createSharedElementStackNavigator();

    return (
        <Stack.Navigator initialRouteName="JobList" headerMode="none">
            <Stack.Screen name="JobList" component={JobList} />
            <Stack.Screen name="JobDetails" component={JobDetails} />
        </Stack.Navigator>
    );
}

function MyJobsNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="MyEmptyJobs" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

function MessagesNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="EmptyMessages" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

function NotificationNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="EmptyNotifications" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

function AccountNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="EmptyAccount" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

function TabNavigator() {
    const Tab = createMaterialBottomTabNavigator();

    return (
        <Tab.Navigator
            initialRouteName="Jobs"
            activeColor="#FFFFFF"
            inactiveColor="#90CBF9"
            shifting={false}
            barStyle={{ backgroundColor: '#2196F3', height: 56 }}>
            <Tab.Screen
                name="Jobs"
                component={JobNavigator}
                options={{
                    tabBarIcon: ({ color }) => (
                        <Icon size={24} name={'magnify'} style={{ color }} />
                    ),
                    tabBarLabel: 'كل العروض',
                }}
            />
            <Tab.Screen
                name="MyJobs"
                component={MyJobsNavigator}
                options={{
                    tabBarIcon: ({ color }) => (
                        <Icon size={24} name={'check-all'} style={{ color }} />
                    ),
                    tabBarLabel: 'عروضي',
                }}
            />
            <Tab.Screen
                name="Messages"
                component={MessagesNavigator}
                options={{
                    tabBarIcon: ({ color }) => (
                        <Icon size={24} name={'message'} style={{ color }} />
                    ),
                    tabBarLabel: 'الرسائل',
                }}
            />
            <Tab.Screen
                name="Notification"
                component={NotificationNavigator}
                options={{
                    tabBarIcon: ({ color }) => (
                        <Icon size={24} name={'bell'} style={{ color }} />
                    ),
                    tabBarLabel: 'الإشعارات',
                }}
            />
            <Tab.Screen
                name="Account"
                component={AccountNavigator}
                options={{
                    tabBarIcon: ({ color }) => (
                        <Icon size={24} name={'account'} style={{ color }} />
                    ),
                    tabBarLabel: 'حسابي',
                }}
            />
        </Tab.Navigator>
    );
}

function LoginNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none" initialRouteName="Login">
            <Stack.Screen name="Login" component={Login} />
        </Stack.Navigator>
    );
}

function RegisterNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none" initialRouteName="Register">
            <Stack.Screen name="Register" component={Register} />
            <Stack.Screen name="Register2" component={Register2} />
            <Stack.Screen name="Register3" component={Register3} />
        </Stack.Navigator>
    );
}

function AuthTabsNavigator() {
    const Tab = createMaterialTopTabNavigator();

    return (
        <Tab.Navigator
            initialRouteName="LoginTab"
            initialLayout={{
                width: Dimensions.get('window').width,
                height: 56,
                marginTop: Constants.statusBarHeight,
            }}
            style={{
                paddingTop: Constants.statusBarHeight + 13,
                backgroundColor: '#FFF',
            }}
            tabBar={(props) => <TabBar {...props} />}
            tabBarOptions={{
                labelStyle: {
                    fontFamily: 'DinBold',
                    fontSize: 14,
                    lineHeight: 21,
                },
                activeTintColor: 'rgb(33, 150, 243)',
                inactiveTintColor: 'rgb(178, 178, 178)',
                style: {
                    backgroundColor: 'transparent',
                    elevation: 0,
                },
                tabMarginRight: 16,
                tabStyle: {
                    alignItems: 'flex-start',
                    paddingLeft: 0,
                    paddingRight: 0,
                    width: 'auto',
                    marginRight: 16,
                },
                contentStyle: {
                    flex: 0.7,
                    flexDirection: 'column',
                    paddingTop: 4,
                    paddingLeft: 25,
                },
                containerStyle: {
                    justifyContent: 'flex-start',
                    flexDirection: 'row-reverse',
                },
                leftContent: (
                    <View
                        style={{
                            flex: 0.3,
                            paddingRight: 14,
                            alignItems: 'flex-end',
                        }}>
                        <Image
                            source={images.logo}
                            style={{ width: 64, height: 64 }}
                        />
                    </View>
                ),
                indicatorStyle: {
                    backgroundColor: 'rgb(33, 150, 243)',
                },
                showIcon: true,
            }}
            swipeEnabled={false}>
            <Tab.Screen
                name="LoginTab"
                component={LoginNavigator}
                options={{
                    tabBarLabel: 'تسجيل الدخول',
                }}
            />
            <Tab.Screen
                name="RegisterTab"
                component={RegisterNavigator}
                options={{
                    tabBarLabel: 'إنشاء حساب جديد',
                }}
            />
        </Tab.Navigator>
    );
}

function MainNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator
            initialRouteName="PreLoader"
            headerMode="none"
            screenOptions={{ animationEnabled: false }}
            mode="modal">
            <Stack.Screen name="App" component={TabNavigator} />
            <Stack.Screen name="Auth" component={AuthTabsNavigator} />
            <Stack.Screen name="GetStarted" component={GetStarted} />
            <Stack.Screen name="PreLoader" component={PreLoader} />
        </Stack.Navigator>
    );
}

function setTopLevelNavigator(navigatorRef) {
    _navigator = navigatorRef;
}

function navigate(routeName, params) {
    _navigator.dispatch(
        NavigationActions.navigate({
            routeName,
            params,
        }),
    );
}

function goBack() {
    _navigator.dispatch(NavigationActions.back());
}

export default {
    navigate,
    setTopLevelNavigator,
    MainNavigator,
};

If i change this line to the following so that the root is the createSharedElementStackNavigator stack it works other wise it breaks, Please note that also changing to createStackNavigator does not break the app but no shared element transition of course

export default {
    navigate,
    setTopLevelNavigator,
    MainNavigator: JobNavigator,
};

ibrahimahmed-io avatar Dec 10 '20 14:12 ibrahimahmed-io

Any luck with this?

alex10791 avatar Feb 16 '21 23:02 alex10791

I have no idea to be honest. You might want to upgrade to the latest release which officially supports React Navigation 5 and 6. https://github.com/IjzerenHein/react-navigation-shared-element/releases/tag/v3.1.2

But I'm not sure it will fix this issue though. react-navigation-shared-element only uses React.useLayoutEffect in some places. It's hard to tell though whether this could cause a stack recursion that you are seeing. I would first try upgrading; and secondly to add a test-case to the example app that reproduces this problem. In that case I can take a closer look at it

IjzerenHein avatar Aug 24 '21 10:08 IjzerenHein

I had the same issue. It was down to the way that I was exporting the stack navigators.
Try moving the stack creation outside the function, as the demo code does.

I.e. Where you have:

function MyJobsNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="MyEmptyJobs" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

Try:

  const Stack = createStackNavigator();
   const MyJobsNavigator = () => (
     <Stack.Navigator headerMode="none">
            <Stack.Screen name="MyEmptyJobs" component={EmptyScreen} />
        </Stack.Navigator>
        )

I did this for all my stacks but it may just be necessary for the ones that use createSharedStackNavigator.

chrisellis-bcgdv avatar Sep 02 '21 07:09 chrisellis-bcgdv

I had the same issue. It was down to the way that I was exporting the stack navigators. Try moving the stack creation outside the function, as the demo code does.

I.e. Where you have:

function MyJobsNavigator() {
    const Stack = createStackNavigator();

    return (
        <Stack.Navigator headerMode="none">
            <Stack.Screen name="MyEmptyJobs" component={EmptyScreen} />
        </Stack.Navigator>
    );
}

Try:

  const Stack = createStackNavigator();
   const MyJobsNavigator = () => (
     <Stack.Navigator headerMode="none">
            <Stack.Screen name="MyEmptyJobs" component={EmptyScreen} />
        </Stack.Navigator>
        )

I did this for all my stacks but it may just be necessary for the ones that use createSharedStackNavigator.

this solved it for me, thank you

akinlekan28 avatar Apr 26 '22 13:04 akinlekan28

Have this problem, but the solution above does not help :(

nazarTrynko avatar Oct 19 '22 10:10 nazarTrynko