Реагируйте на навигацию 6. Переопределите конфигурацию заголовка родительского навигатора с экрана внутри дочернего навигатора

#javascript #react-native #navigation #react-navigation

Вопрос:

У меня есть BottomTab навигатор, вложенный в Stsck навигатор. И заголовок настраивается с помощью стека screenOptions :

 function AppStackNavigator() {  return (  lt;Stack.Navigator screenOptions={getScreenOptions}gt;  lt;Stack.Screen name="BottomTab" component={BottomTabNavigator}/gt;  ...  lt;/Stack.Navigatorgt;  )   const getScreenOptions = ({route, navigation}) =gt; {  // crazy logic ...   return {  headerLeft: getHeaderLeft,  headerRight: getHeaderRight,  ...  }  }  }  

И в BottomTaB навигаторе у меня есть экран под названием Target . Обратите внимание, что значение headerShown установлено false здесь.

 function BottomTabNavigators() {  return (  lt;Tab.Navigator  screenOptions={{headerShown: false}}  tabBar={props =gt; lt;MyTabBar {...props}/gt;}  gt;  lt;Tab.Screen name="Target" component={TargetScreen}/gt;  lt;/Tab.Navigatorgt;  ) }  

На целевом экране я переопределяю headerRight РОДИТЕЛЬСКИЙ навигатор, потому что мне нужно прямое взаимодействие между заголовком и методом ( methodThatIsOnlyAccessableHere ), который доступен только внутри этого экрана:

 function TargetScreen() {   const methodThatIsOnlyAccessableHere = () =gt; { ... }   useLayoutEffect(() =gt; {  const getHeaderRight = () =gt; {  // call methodThatIsOnlyAccessableHere  ...  }   const parentNavigator = navigation.getParent()  parentNavigator.setOptions({  headerRight: getHeaderRight,  })   }, [navigation]) }  

Текущее поведение:

Конфигурация заголовка верхнего уровня ( screenOptions в навигаторе стеков) работает отлично. При переходе на Target экран конфигурация переопределенного заголовка (использование setOptions ) станет активной. Однако при выходе с этого экрана эта переопределенная конфигурация все еще остается активной (Нежелательное поведение).

Желаемое поведение

При выходе Target из экрана конфигурация заголовка верхнего уровня должна стать активной, а переопределенная конфигурация должна стать недействительной.

Почему это мой дизайнерский выбор ?

Я всегда скрываю вложенный заголовок навигатора (заголовок BottomTab навигатора) и настраиваю заголовок навигатора верхнего уровня (родительский) ( Stack навигатор) на основе состояния дочернего навигатора. Я не могу переместить конфигурацию заголовка Target экрана в родительский, потому что в этом случае у меня не будет доступа methodThatIsOnlyAccessableHere .

Ответ №1:

Вам нужно будет обновить headerRight еще раз. Например: используйте очистку вашего useLayoutEffect крючка.

 useLayoutEffect(() =gt; {  const getHeaderRight = () =gt; {  // call methodThatIsOnlyAccessableHere  ...  }   const parentNavigator = navigation.getParent()  parentNavigator.setOptions({  headerRight: getHeaderRight,  })   // cleanup  return () =gt; {  parentNavigator.setOptions({  headerRight: null  })  }   }, [navigation])  

Комментарии:

1. При выходе из целевого экрана эта очистка сделает переопределенную конфигурацию безрезультатной (что правильно), однако конфигурация заголовка верхнего уровня снова не будет активна (это неверно ). Я уже упоминал об этом в желаемом поведении.

Ответ №2:

Я предполагаю, что ваша функция TargetScreen запускается для каждого вызова маршрута, чтобы по возможности переопределить родительский элемент. Если это правда, вы можете сбросить параметры в начале вашего крючка useLayoutEffect, и, опять же, предполагая, что ваш вызов getParent() проверяет, к какой странице вы обращаетесь, он сбросит текущую навигацию по странице всякий раз, когда эффект вызывается, не влияя на его переопределяющий вызов.