React Navigation v5: 탭을 떠난 후 탭 내부의 스택 재설정

Originally published on reactnativeschool.com



문제: 탭 내부에 스택 탐색기가 있고 다른 탭으로 이동할 때 방금 떠난 탭 내부의 스택 탐색기를 재설정하려고 합니다.

예시




import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CommonActions, StackActions } from '@react-navigation/native';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title="Details" onPress={() => navigation.push('Details')} />
    </View>
  );
}

function DetailsScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}

function SettingsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Settings Screen</Text>
      <Button
        title="Settings Details"
        onPress={() => navigation.push('SettingsDetail')}
      />
    </View>
  );
}

function SettingsDetailScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Settings Details Screen</Text>
    </View>
  );
}

const Stack = createStackNavigator();
const Stack2 = createStackNavigator();
const Tab = createBottomTabNavigator();

const HomeStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Details" component={DetailsScreen} />
  </Stack.Navigator>
);

const SettingsStack = () => (
  <Stack2.Navigator>
    <Stack2.Screen name="Settings" component={SettingsScreen} />
    <Stack2.Screen name="SettingsDetail" component={SettingsDetailScreen} />
  </Stack2.Navigator>
);

function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="HomeTab" component={HomeStack} />
        <Tab.Screen name="SettingsTab" component={SettingsStack} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

export default App;


이 예제 앱의 경우 해당 탭을 떠나는 경우에만 홈 스택을 재설정하려고 합니다. 설정에서 중첩된 화면에 있는 경우 그대로 두고 싶습니다.



해결책



이것은 훌륭한 솔루션은 아니지만("dangerouslyGetState"에 주목) 충분히 잘 작동하는 것 같습니다. 이 솔루션은 이Github issue에서 제공되는 솔루션 위에 구축됩니다.

// ...

// https://github.com/react-navigation/react-navigation/issues/8583
const TAB_TO_RESET = 'HomeTab';
const resetHomeStackOnTabPress = ({ navigation, route }) => ({
  tabPress: (e) => {
    const state = navigation.dangerouslyGetState();

    if (state) {
      // Grab all the tabs that are NOT the one we just pressed
      const nonTargetTabs = state.routes.filter((r) => r.key !== e.target);

      nonTargetTabs.forEach((tab) => {
        // Find the tab we want to reset and grab the key of the nested stack
        const tabName = tab?.name;
        const stackKey = tab?.state?.key;

        if (stackKey && tabName === TAB_TO_RESET) {
          // Pass the stack key that we want to reset and use popToTop to reset it
          navigation.dispatch({
            ...StackActions.popToTop(),
            target: stackKey,
          });
        }
      });
    }
  },
});

function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen
          name="HomeTab"
          component={HomeStack}
          // Note that resetHomeStackOnTabPress should be added to each tab
          listeners={resetHomeStackOnTabPress}
        />
        <Tab.Screen
          name="SettingsTab"
          component={SettingsStack}
          listeners={resetHomeStackOnTabPress}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

export default App;




탭을 변경할 때 모든 스택을 재설정하려면 tabName === TAB_TO_RESET 확인 표시를 제거할 수 있습니다.

좋은 웹페이지 즐겨찾기