简体   繁体   中英

React Native Navigation: Reset Stack Navigator

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.

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>
  )
}

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.

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>
  )

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM