Перейти к содержанию

Привет React Navigation

В веб-браузере ссылки на различные страницы можно размещать с помощью тега ссылки (<a>). Когда пользователь нажимает на ссылку, URL-адрес помещается в стек истории браузера. Когда пользователь нажимает кнопку "Назад", браузер поднимает элемент с вершины стопки истории, поэтому активной страницей становится ранее посещенная страница. В React Native нет встроенного представления о глобальном стеке истории, как в браузере, и именно здесь в дело вступает React Navigation.

Встроенный стековый навигатор React Navigation обеспечивает переход между экранами и управление историей навигации. Если в вашем приложении используется только один навигатор стека, то концептуально это похоже на то, как веб-браузер управляет состоянием навигации - ваше приложение выталкивает и убирает элементы из навигационного стека по мере взаимодействия с пользователем, в результате чего пользователь видит разные экраны. Ключевое различие между тем, как это работает в веб-браузере и в React Navigation, заключается в том, что нативный стековый навигатор React Navigation обеспечивает жесты и анимацию, которые можно ожидать на Android и iOS при переходе между маршрутами в стеке.

Начнем с демонстрации наиболее распространенного навигатора, createNativeStackNavigator.

Установка библиотеки native stack navigator

Библиотеки, которые мы установили до сих пор, являются строительными блоками и общим фундаментом для навигаторов, и каждый навигатор в React Navigation живет в своей собственной библиотеке. Для использования нативного стекового навигатора нам необходимо установить @react-navigation/native-stack :

1
npm install @react-navigation/native-stack

💡 @react-navigation/native-stack зависит от react-native-screens и других библиотек, которые мы установили в [Getting started] (getting-started.md). Если они еще не установлены, перейдите на эту страницу и следуйте инструкциям по установке.

Создание нативного навигатора стека

createNativeStackNavigator - это функция, которая возвращает объект, содержащий 2 свойства: Screen и Navigator. Оба они являются компонентами React, используемыми для настройки навигатора. В качестве дочерних элементов Navigator должен содержать элементы Screen для определения конфигурации маршрутов.

NavigationContainer - это компонент, который управляет нашим навигационным деревом и содержит navigation state. Этот компонент должен обернуть всю структуру навигаторов. Обычно мы размещаем этот компонент в корне нашего приложения, который, как правило, является компонентом, экспортируемым из App.js.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// In App.js in a new project
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

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

const Stack = createNativeStackNavigator();

function App() {
    return (
        <NavigationContainer>
            <Stack.Navigator>
                <Stack.Screen
                    name="Home"
                    component={HomeScreen}
                />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

export default App;

Базовое приложение с использованием стекового навигатора

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

Регистр имени маршрута не имеет значения - вы можете использовать строчную home или заглавную Home, это зависит от вас. Мы предпочитаем писать имена маршрутов с заглавной буквы.

Конфигурирование навигатора

Вся конфигурация маршрута задается в виде пропсов для нашего навигатора. Мы не передавали никаких пропсов навигатору, поэтому он просто использует конфигурацию по умолчанию.

Давайте добавим второй экран в наш нативный стековый навигатор и настроим, чтобы экран Home отображался первым:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function DetailsScreen() {
    return (
        <View
            style={{
                flex: 1,
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <Text>Details Screen</Text>
        </View>
    );
}

const Stack = createNativeStackNavigator();

function App() {
    return (
        <NavigationContainer>
            <Stack.Navigator initialRouteName="Home">
                <Stack.Screen
                    name="Home"
                    component={HomeScreen}
                />
                <Stack.Screen
                    name="Details"
                    component={DetailsScreen}
                />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

Теперь в нашем стеке есть два маршрута, маршрут Home и маршрут Details. Маршрут может быть задан с помощью компонента Screen. Компонент Screen принимает параметр name, который соответствует имени маршрута, по которому мы будем переходить, и параметр component, который соответствует компоненту, который он будет отображать.

Здесь маршруту Home соответствует компонент HomeScreen, а маршруту Details - компонент DetailsScreen. Начальным маршрутом для стека является маршрут Home. Попробуйте изменить его на Details и перезагрузите приложение (Fast Refresh в React Native не будет обновлять изменения от initialRouteName, как вы могли бы ожидать), обратите внимание, что теперь вы увидите экран Details. Затем измените его обратно на Home и перезагрузите еще раз.

Примечание

Параметр component принимает компонент, а не функцию рендеринга. Не передавайте встроенную функцию (например, component={() => <HomeScreen />}), иначе ваш компонент будет размонтирован и снова смонтирован, потеряв все состояние при повторном рендеринге родительского компонента. Альтернативные варианты см. в разделе Передача дополнительных пропсов.

Указание опций

Каждый экран в навигаторе может задавать некоторые опции для него, например, заголовок для отображения в заголовке. Эти опции могут быть переданы в пропсе options для каждого компонента экрана:

1
2
3
4
5
<Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{ title: 'Overview' }}
/>

Иногда мы хотим задать одинаковые параметры для всех экранов навигатора. Для этого мы можем передать навигатору пропс screenOptions.

Передача дополнительных пропсов

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

  1. Использовать React context и обернуть навигатор провайдером контекста для передачи данных на экраны (рекомендуется).

  2. Использовать обратный вызов рендеринга для экрана вместо указания свойства component:

    1
    2
    3
    4
    5
    <Stack.Screen name="Home">
        {(props) => (
            <HomeScreen {...props} extraData={someData} />
        )}
    </Stack.Screen>
    

По умолчанию React Navigation применяет оптимизацию к компонентам экрана для предотвращения ненужного рендеринга. Использование обратного вызова рендеринга устраняет эти оптимизации. Поэтому, если вы используете обратный вызов рендеринга, вам необходимо убедиться, что вы используете React.memo или React.PureComponent для своих экранных компонентов, чтобы избежать проблем с производительностью.

Что дальше?

Естественным вопросом на этом этапе является: "Как мне перейти от маршрута Home к маршруту Details?". Этот вопрос рассматривается в следующем разделе.

Резюме

  • В React Native нет встроенного API для навигации, как в веб-браузере. Его предоставляет React Navigation, а также жесты и анимации для перехода между экранами в iOS и Android.

  • Stack.Navigator - это компонент, который принимает конфигурацию маршрута в качестве своих дочерних элементов с дополнительными пропсами для настройки и отображает наш контент.

  • Каждый компонент Stack.Screen принимает пропс name, который ссылается на имя маршрута, и пропс component, который указывает компонент для рендеринга маршрута. Это два обязательных пропса.

  • Чтобы указать начальный маршрут в стеке, укажите initialRouteName в качестве пропса для навигатора.

  • Для указания опций, специфичных для экрана, мы можем передать пропс options в Stack.Screen, а для общих опций - screenOptions в Stack.Navigator.

Ссылки

Комментарии