Expo router with Expo layout cause inifity loop.

  1. SDK Version: ^48.0.7
  2. Platforms(Android/iOS/web/all): IOS & ANDROID

I got a “reset password” button in my “signIn” component, when user press the button it will route user to the component “resetPwd.tsx”.
But it will cause infinity render loop beetween “resetPwd.tsx” and “_layout.tsx”
Here is the log

 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 $29383e587d62412a$export$9f8ac96af4b1b2ae (created by NativeBaseProvider)
    in ToastProvider (created by NativeBaseProvider)
    in PortalProvider (created by NativeBaseProvider)
    in HybridProvider (created by NativeBaseProvider)
    in ResponsiveQueryProvider (created by NativeBaseProvider)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by NativeBaseProvider)
    in NativeBaseConfigProviderProvider (created by NativeBaseProvider)
    in NativeBaseProvider (created by Layout)
    in Layout
    in Try
    in Unknown
    in Unknown (created by Route(sign_in))
    in Route (created by Route(sign_in))
    in LocationProvider (created by Route(sign_in))
    in Route(sign_in) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by QualifiedSlot)
    in QualifiedSlot (created by DefaultNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by QualifiedNavigator)
    in QualifiedNavigator (created by Navigator)
    in Navigator (created by DefaultNavigator)
    in DefaultNavigator
    in Unknown (created by Route())
    in Route (created by Route())
    in LocationProvider (created by Route())
    in Route() (created by RootRoute)
    in RootRoute (created by ContextNavigator)
    in InitialRootStateProvider (created by ContextNavigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by NavigationContainer)
    in NavigationContainer (created by ContextNavigator)
    in RootRouteNodeProvider (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by ExpoRoot)
    in RCTView (created by View)
    in View (created by GestureHandlerRootView)
    in GestureHandlerRootView (created by GestureHandler)
    in GestureHandler (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by withDevTools(App))
    in withDevTools(App) (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent)
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd...
 LOG  render layout...
 LOG  render ResetPwd..

Here is the “signIn” component content of how to handle the event when user press the “reset password” button.

<Link onPress={() => {
                            router.push('sign_in/resetPwd')
                        }} _text={{
                            fontSize: "xs",
                            fontWeight: "500",
                            color: "indigo.500"
                        }} alignSelf="flex-end" mt="1">
                            {translateWithKey<LoginPageKeys>('forgetPwd')}
                        </Link>

And here is my project strucutre

The conetnt of resetPwd.tsx

import { useRouter } from "expo-router";
import { View, Text, NativeBaseProvider, Box, Center, Button } from "native-base";

export default function ResetPwd() {
    const router = useRouter()
    return (
        <Box>
            <Text margin={"auto"}>ResetPwd!!!</Text>
            <Button onPress={() => {
                router.back()
            }}>Back</Button>
        </Box>
    )
}

The content of _layout.tsx under the “sign_in” folder.

import { KeyboardAvoidingView, NativeBaseProvider, View, Text } from "native-base";
import { Keyboard, Pressable, SafeAreaView } from "react-native";
import RenderWithLogo from "../../component/react_native_component/renderWithLogo";
import { Slot } from "expo-router";

export { ErrorBoundary } from '../../component/utils/errorBoundary'

export default function Layout() {
    console.log('render layout...')
    return <NativeBaseProvider>
        <KeyboardAvoidingView behavior='position'>
                <Pressable onPress={() => {
                    Keyboard.dismiss()
                }}>
                    <RenderWithLogo toRender={<Slot />} />
                </Pressable>
        </KeyboardAvoidingView>
    </NativeBaseProvider>
}
import { ReactElement } from "react";
import { Box, Center, Stack } from 'native-base'
import { Image } from 'expo-image'

interface Props {
    toRender: ReactElement
}

export default function RenderWithLogo(props: Props) {
    return (<Box height={'full'} alignItems={'stretch'} flexDirection={'column'} flexWrap={'wrap'} justifyContent={'space-between'} flexGrow={3}>
        <Box marginTop={"10%"} flex={0.8} flexDirection={"row"}>
            <Image
                style={{ flex: 1 }}
                source={require('../../assets/zhengboLogo.png')}
                contentFit='fill'
            />
        </Box>

        <Box flex={2.2} flexDirection={"row"} flexWrap={"wrap"}>
            {props.toRender}
        </Box>
    </Box>)
}

I dont know what should I do, Thanks you all.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.