4

I'm using React Navigation 5.

At the top I have a Drawer navigator, with the following screens:

  <Drawer.Navigator>
    <Drawer.Screen name="One" component={StackNavigatorOne} />
    <Drawer.Screen name="Two" component={StackNavigatorTwo} />
    <Drawer.Screen name="Three" component={StackNavigatorThree} />
  <Drawer.Navigator/>

Within StackNavigatorOne, I have a stack navigator,

<Stack.Navigator>
  <Stack.Screen name="Screen1" component={Screen1} />
  <Stack.Screen name="Screen2" component={Screen2} />
  <Stack.Screen name="Screen2" component={Screen3} />
</Stack.Navigator>

From the Drawer Navigator, if the user navigates to Stack Navigator One, and then moves to Screen2, the Screen2 stays on top. Now, if the user opens drawer navigation and again clicks on Stack Navigator One, he will be on Screen 2 only because Screen 2 is on top in that stack.

However, what I need is that when the user clicks the DrawerScreen One, it should always go to Screen1 of StackNavigatorOne. Is it possibe to reset the screens in StackNavigatorOne irrespective of which screen the user is on, when he click the DrawerScreen One in the drawer?

Thanks.

1
  • Does applying initialRouteName for the stack makes this possible? Commented Dec 27, 2020 at 17:13

3 Answers 3

4
+200

The simplest solution is use unmountOnBlur: true.

There is a props unmountOnBlur: true on DrawerNavigator's screenOptions. You can use it to unmount the stack of the screen when user move from one drawer screen to another.

You can use it like this :

<Drawer.Navigator
  screenOptions={{
    unmountOnBlur: true
  }}
>
  <Drawer.Screen name="One" component={StackNavigatorOne} />
  <Drawer.Screen name="Two" component={StackNavigatorTwo} />
  <Drawer.Screen name="Three" component={StackNavigatorThree} />
<Drawer.Navigator/>

You can find more detail about unmountOnBlue here.

Sign up to request clarification or add additional context in comments.

6 Comments

This will work for the entire stack, or just specific screens within the stack? In my case, it will be useful only if the entire stack is unmounted when all screens in that stack are blurred.
it will unmount your drawer screen which is itself stack navigator. So, it will work with entire stack.
Your answer worked great for me. What do you think of Muhammad's answer? Which is a better solution - your's or his?
Muhammad's answer may also work but there may a problem when you are on "Screen2" of "StackNavigatorOne" and from there you navigate to "StackNavigatorTwo"s "Screen1". Because whenever "StackNavigator" get fouced it may reset stack with popToTop(), whether in my answer it automatically detect if user is redirected from the "Drawer" then and only then it's reset the stack. Whether in Muhammad's answer stack may be reset every time when any of stack got focused.
how to solved "Whether in Muhammad's answer stack may be reset every time when any of stack got focused" this?? i dont want to use unmountOnBlur it will re render screen.
|
4

Solution 1:

you can use unmountOnBlur:true in screenOptions props in drawer like this DOCS

<Drawer.Navigator
  screenOptions={{
    unmountOnBlur: true
  }}
>
  <Drawer.Screen name="One" component={StackNavigatorOne} />
  <Drawer.Screen name="Two" component={StackNavigatorTwo} />
  <Drawer.Screen name="Three" component={StackNavigatorThree} />
<Drawer.Navigator/>

Solution 2:

props.navigation.canGoBack() tells us if user can goBack or not

popToTop will pop all screen except first screen

if navigation stack is not empty then we have to use popToTop for reset stack on focus on StackNavigatorOne like this

import {  StackActions } from '@react-navigation/native';

function StackNavigatorOne = (props) => {
  useEffect(() => {
    props.navigation.addListener('focus', () => {
        if(props.navigation.canGoBack())
        {
          props.navigation.dispatch(StackActions.popToTop());
        }
     });
    }, [])

  return (
    <Stack.Navigator key={key}>
      <Stack.Screen name="Screen1" component={Screen1} />
      <Stack.Screen name="Screen2" component={Screen2} />
      <Stack.Screen name="Screen2" component={Screen3} />
    </Stack.Navigator>
  )
}

3 Comments

I didn't quite understand how this is working? Can you please explain. What will happen if StackNavigatorOne is already in focus?
solution 2 work great its does not reset the state while reset the stack only very usefull.
it is reset all stack Navigator i:e StackNavigatorTwo StackNavigatorThree etc but I want to reset only one kindly help.
1

You could reset StackNavigatorOne everytime it's not focused, for instance:

function StackNavigatorOne = (props) => {
  const [key, setKey] = useState(0)
  const isFocused = useIsFocused()

  useEffect(() => {
    if (!isFocused) setKey((k) => k + 1)
  }, [isFocused])

  return (
    <Stack.Navigator key={key}>
      <Stack.Screen name="Screen1" component={Screen1} />
      <Stack.Screen name="Screen2" component={Screen2} />
      <Stack.Screen name="Screen2" component={Screen3} />
    </Stack.Navigator>
  )

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.