Home > Enterprise >  React-Native, Navigation, Drawers and passing inline functions with props
React-Native, Navigation, Drawers and passing inline functions with props

Time:12-18

I have a Drawer Navigator nested inside a Stack navigator. It all works fine but I get the following warning:-

Looks like you're passing an inline function for 'component' prop for the screen 'Home' (e.g. component={() => }). Passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour.

Here is the code.

const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [initialRoute, setInitialRoute] = React.useState("");

const handleSignOut = () => {
    // TODO implement sign out mechanism
};

return (
    <NavigationContainer>{
        <Stack.Navigator initialRouteName="Sign In"         >
            {isAuthenticated ? (
                <Stack.Screen name="Home"
                    component={() => <HomeDrawer initialRoute={initialRoute} handleSignOut={handleSignOut}/>}
                    options={({ route, navigation }) => ({
                        headerTitle: getFocusedRouteNameFromRoute(route),
                        headerLeft: () => (
                            <Button
                                title="Menu"
                                onPress={() =>
                                    navigation.dispatch(DrawerActions.toggleDrawer())
                                }
                            />
                        ),
                        headerRight: () => (
                            <Button onPress={handleSignOut} title="Sign Out" />
                        ),
                    })}
                />
            ) : (

            ...

I fixed the warning by moving the component, but now the Drawer has stop working completely and I get this error:-

The action 'TOGGLE_DRAWER' was not handled by any navigator. Is your screen inside a Drawer navigator?

Here is the new code.

const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [initialRoute, setInitialRoute] = React.useState("");

const handleSignOut = () => {
    // TODO implement sign out mechanism
};

const Draw = () => {<HomeDrawer initialRoute={initialRoute} handleSignOut={handleSignOut}/>};

return (
    <NavigationContainer>{
        <Stack.Navigator initialRouteName="Sign In"         >
            {isAuthenticated ? (
                <Stack.Screen name="Home"
                    component={Draw}
                    options={({ route, navigation }) => ({
                        headerTitle: getFocusedRouteNameFromRoute(route),
                        headerLeft: () => (
                            <Button
                                title="Menu"
                                onPress={() =>
                                    navigation.dispatch(DrawerActions.toggleDrawer())
                                }
                            />
                        ),
                        headerRight: () => (
                            <Button onPress={handleSignOut} title="Sign Out" />
                        ),
                    })}
                />
            ) : (

            ...

I'm new to React-Native and on a steep learning curve. I've read a bunch of tutorials but stumped on this one. I can see I need to pass initialRoute at least, but not sure how to do that. A fix with an explanation would be great.

CodePudding user response:

you can also use useNavigation() in button onPress

CodePudding user response:

I found the answer in the end. It was pretty straight forward, but not when there are so many things to learn at once :-) When I moved the component like so it all worked.

<Stack.Screen name="Home"
    options={({ route, navigation }) => ({
        headerTitle: getFocusedRouteNameFromRoute(route),
        headerLeft: () => (
            <Button
                title="Menu"
                onPress={() =>
                    navigation.dispatch(DrawerActions.toggleDrawer())
                }
            />
        ),
        headerRight: () => (
            <Button onPress={handleSignOut} title="Sign Out" />
        ),
    })}
>
    {(props) => (
        <HomeDrawer {...props} initialRoute={initialRoute} handleSignOut={handleSignOut} />
    )}
</Stack.Screen>
<Stack.Screen name="TEST" component={TestScreen}
    screenOptions={{ headerShown: true }}
    options={{ headerTitle: "Hello" }}
/>
  • Related