Перейти к основному содержимому

Вложенные навигаторы

Вложение навигаторов означает отображение навигатора внутри экрана другого навигатора, например:

const Home = () => {  return (    <Tab.Navigator>      <Tab.Screen name="Feed" component={Feed} />      <Tab.Screen name="Messages" component={Messages} />    </Tab.Navigator>  )}
const App = () => {  return (    <NavigationContainer>      <Stack.Navigator>        <Stack.Screen          name="Home"          component={Home}          options={{ headerShown: false }}        />        <Stack.Screen name="Profile" component={Profile} />        <Stack.Screen name="Settings" component={Settings} />      </Stack.Navigator>    </NavigationContainer>  )}

В приведенном выше примере компонент Home содержит навигатор с табами. Компонент Home также используется для экрана Home в вашем навигаторе стека внутри компонента App. Итак, здесь навигатор вкладок вложен в навигатор стека:

  • Stack.Navigator
    • Home (Tab.Navigator)
      • Feed (Screen)
      • Messages (Screen)
    • Profile (Screen)
    • Settings (Screen)

Вложенные навигаторы работают так же, как и обычные компоненты. Чтобы добиться желаемого поведения, часто необходимо вложить несколько навигаторов.

Как вложение навигаторов влияет на поведение#

При вложении навигаторов следует помнить о некоторых вещах:

Каждый навигатор хранит свою историю навигации.#

Например, когда вы нажимаете кнопку «Назад», находясь на экране во вложенном навигаторе стека, он вернется к предыдущему экрану внутри вложенного стека, даже если в качестве родителя есть другой навигатор.

У каждого навигатора свои параметры#

Например, указание опции title на экране, вложенном в дочерний навигатор, не повлияет на заголовок, отображаемый в родительском навигаторе.

Если вы хотите добиться такого поведения, см. Руководство для параметры экрана с вложенными навигаторами. Это может быть полезно, если вы визуализируете навигатор вкладок внутри навигатора стека и хотите показать заголовок активного экрана внутри навигатора вкладок в заголовке навигатора стека.

У каждого экрана в навигаторе свои параметры#

Например, любые параметры params, переданные на экран во вложенном навигаторе, находятся в prop route этого экрана и недоступны с экрана в родительском или дочернем навигаторе.

Если вам нужно получить доступ к параметрам родительского экрана с дочернего экрана, вы можете использовать React Context, чтобы предоставить параметры дочерним элементам.

Действия навигации обрабатываются текущим навигатором и всплывают, если не могут быть обработаны#

Например, если вы вызываете navigation.goBack() во вложенном экране, он вернется в родительский навигатор только в том случае, если вы уже находитесь на первом экране навигатора. Другие действия, такие как navigate, работают аналогично, то есть навигация будет происходить во вложенном навигаторе, и если вложенный навигатор не может ее обработать, то родительский навигатор попытается ее обработать. В приведенном выше примере при вызове navigate('Messages') внутри экрана Feed вложенный навигатор вкладок будет обрабатывать его, но если вы вызываете navigate('Settings'), родительский навигатор стека будет обрабатывать его.

Специальные методы навигатора доступны в навигаторах, вложенных внутри#

Например, если у вас есть стек внутри навигатора drawer, методы drawer openDrawer, closeDrawer, toggleDrawer и т.д. Также будут доступны в navigation на экране внутри навигатора стека. Но предположим, что у вас есть навигатор стека в качестве родителя drawer, тогда экраны внутри навигатора стека не будут иметь доступа к этим методам, потому что они не вложены внутри drawer.

Точно так же, если у вас есть навигатор по вкладкам внутри навигатора стека, экраны в навигаторе вкладок получат методы push и replace для стека в их свойствах navigation.

Если вам нужно отправить действия вложенным дочерним навигаторам от родительского элемента, вы можете использовать navigation.dispatch:

navigation.dispatch(DrawerActions.toggleDrawer())

Вложенные навигаторы не получают родительские события#

Например, если у вас есть навигатор стека, вложенный в навигатор вкладок, экраны в навигаторе стека не будут получать события, генерируемые родительским навигатором вкладок, например tabPress, при использовании navigation.addListener.

Чтобы получать события от родительского навигатора, вы можете явно прослушивать родительские события с помощью navigation.getParent():

const unsubscribe = navigation.getParent().addListener ('tabPress', (e) => {  // Сделай что-нибудь})

Пользовательский интерфейс родительского навигатора отображается поверх дочернего навигатора#

Например, если вы вложите навигатор стека в навигатор Drawer, вы увидите, что Drawer появляется над заголовком навигатора стека. Однако, если вы вложите навигатор Drawer внутри стека, Drawer появится под заголовком стека. Это важный момент, который следует учитывать при принятии решения о размещении ваших навигаторов.

Done ✅#

Чтобы узнать, насколько хорошо вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в боте Telegram.

Sumerian school

Links#

React Navigation

Contributors ✨#

Thanks goes to these wonderful people (emoji key):


Dmitriy Vasilev

📖💲

Become a Patron!