React Navigation — это популярная библиотека для организации маршрутизации и навигации в приложении React Native.
Эта библиотека помогает решить проблему навигации между различными экранами и использования общих данных различными экранами.
После изучения данного руководства у вас в распоряжении будет самая элементарная социальная сеть. Она будет отображать количество связей, которое есть у пользователя, и обеспечит метод установления связи с новыми друзьями. Вы сможете использовать это образец приложения для изучения возможностей навигации между экранами мобильного приложения, реализуемых с помощью react-navigation
.
Для завершения данного обучающего модуля вам потребуется:
Примечание: если у вас есть опыт работы с react-navigation
в прошлом, вы можете заметить ряд различий. Вы можете ознакомиться с документацией, где вы найдете информацию по миграции с версии 3.x и миграции с версии 4.x.
Работоспособность инструкция данного руководства была проверена на Node v14.7.0, npm
v6.14.7, react
v16.13.1, react-native
v0.63.2, @react-navigation/native
v5.7.3 и @react-navigation/stack
v5.9.0.
В первую очередь необходимо создать новое приложение React Native с помощью следующей команды в терминале:
- npx react-native init MySocialNetwork --version 0.63.2
Затем перейдите в новый каталог:
- cd MySocialNetwork
Запустите приложение для iOS:
- npm run ios
Или воспользуйтесь Android:
- npm run android
Примечание: в случае возникновения проблем вы можете ознакомиться со статьей, посвященной устранению проблем с React Native CLI.
В результате будет создана заготовка проекта. В настоящее время он не очень походит на социальную сеть. Давайте исправим это.
Откройте файл App.js
:
- nano App.js
Замените содержимое App.js
на следующий код, отображающий приветственное сообщение:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Welcome to MySocialNetwork!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
Сохраните файл. Теперь, когда вы запустите приложение, сообщение Welcome to MySocialNetwork! будет отображаться в вашем эмуляторе.
В следующем шаге мы добавим в наше приложение новые экраны.
HomeScreen
и FriendsScreen
В настоящее время у вас есть один экран, отображающий приветственное сообщение. В этом шаге мы создадим два новых экрана для вашего приложения: HomeScreen
и FriendsScreen
.
HomeScreen
Вашему приложению потребуется домашний экран HomeScreen
. Экран HomeScreen
будет отображать количество друзей, уже находящихся в вашей сети.
Возьмите код из файла App.js
и добавьте его в новый файл с именем HomeScreen.js
:
- cp App.js HomeScreen.js
Откройте файл HomeScreen.js
:
- nano HomeScreen.js
Измените содержание файла HomeScreen.js
для использования экрана HomeScreen
вместо экрана App
:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have (undefined) friends.</Text>
</View>
);
}
}
// ...
export default HomeScreen;
Данный код будет генерировать сообщение-заглушку You have (undefined) friends. Точное значение вы получите позже.
FriendsScreen
Вашему приложению также потребуется дополнительный экран FriendsScreen
. На экране FriendsScreen
вы сможете добавлять новых друзей.
Возьмите код из файла App.js
и добавьте его в новый файл с именем FriendsScreen.js
:
- cp App.js FriendsScreen.js
Откройте файл FriendsScreen.js
:
- nano FriendsScreen.js
Измените содержание файла FriendsScreen.js
для использования экрана FriendsScreen
вместо экрана App
:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
</View>
);
}
}
// ...
export default FriendsScreen;
Данный код будет добавлять текст Add friends here! в сообщение.
На данный момент у вас есть экраны HomeScreen
и FriendsScreen
. Однако вы не можете перемещаться между этими экранами. Вы реализуете данный функционал в следующем шаге.
StackNavigator
в React NavigationДля навигации между экранами вы будете использовать StackNavigator
. StackNavigator
работает точно так же, как стек вызовов. Каждый экран, на который вы переходите, помещается на самый верх стека. Каждый раз, когда вы нажимаете кнопку назад, экраны удаляются с верхней части стека.
Сначала установите @react-navigation/native
:
- npm install @react-navigation/native@5.7.3
Затем установите @react-navigation/stack
и соответствующие зависимости:
- npm install @react-navigation/stack@5.9.0 @react-native-community/masked-view@0.1.10 react-native-screens@2.10.1 react-native-safe-area-context@3.1.4 react-native-gesture-handler@1.7.0
Примечание: если вы выполняете разработку под iOS, вам, возможно, потребуется перейти в каталог ios
и запустить команду pod install
.
Затем снова откройте файл App.js
:
- nano App.js
Добавьте в поддержку NavigationContainer
и createStackNavigator
в файл App.js
:
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
Затем замените содержимое функции render
:
// ...
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
Внутри <Stack.Navigator>
добавьте компонент HomeScreen
:
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
const Stack = createStackNavigator();
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
Данный код создает очень компактный стек для вашего навигатора с одним экраном: HomeScreen
.
Внутри <Stack.Navigator>
добавьте компонент FriendsScreen
:
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
import FriendsScreen from './FriendsScreen';
const Stack = createStackNavigator();
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Friends"
component={FriendsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
Этот код добавляет в навигатор экран FriendsScreen
.
Примечание: данный способ отличается от того, как createStackNavigator
использовался в предыдущих версиях React Navigation.
Теперь навигатор знает о двух ваших экранах.
HomeScreen
и FriendsScreen
В конце добавьте кнопки для перехода между двумя экранами.
В файле HomeScreen.js
добавьте следующий код:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have (undefined) friends.</Text>
<Button
title="Add some friends"
onPress={() =>
this.props.navigation.navigate('Friends')
}
/>
</View>
);
}
}
// ...
В файле FriendsScreen.js
добавьте следующий код:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
// ...
Давайте обсудим элемент this.props.navigation
. Пока ваш экран включен в StackNavigator
, он автоматически наследует множество полезных свойств объекта navigation
. В этом случае вы использовали функцию navigate
для перемещения на другую страницу.
Если вы сейчас откроете эмулятор, то сможете переходить между экранами HomeScreen
и FriendsScreen
.
Context
для передачи данных между экранамиВ этом шаге мы создадим массив возможных друзей — Alice
, Bob
и Sammy
— и пустой массив текущих друзей. Также нам потребуется создать функционал, позволяющий пользователю добавлять возможных друзей к своим текущим друзьям.
Откройте App.js
:
- nano App.js
Добавьте в состояние компонента элементы possibleFriends
и currentFriends
:
// ...
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
possibleFriends: [
'Alice',
'Bob',
'Sammy',
],
currentFriends: [],
}
}
// ...
}
// ...
Далее добавьте функцию для перемещения возможного друга в список текущих друзей:
// ...
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
possibleFriends: [
'Alice',
'Bob',
'Sammy',
],
currentFriends: [],
}
}
addFriend = (index) => {
const {
currentFriends,
possibleFriends,
} = this.state
// Pull friend out of possibleFriends
const addedFriend = possibleFriends.splice(index, 1)
// And put friend in currentFriends
currentFriends.push(addedFriend)
// Finally, update the app state
this.setState({
currentFriends,
possibleFriends,
})
}
// ...
}
// ...
На этом мы завершили разработку функционала для добавления друзей.
FriendsContext
в приложение
Теперь вы можете добавлять друзей в файле App.js
, но вам может потребоваться добавлять их в файле FriendsScreen.js
и отображать количество друзей в файле HomeScreen.js
. Поскольку данный проект разрабатывается с помощью React, вы можете внедрить данный функционал на ваши экраны с помощью контекста.
Примечание: в предыдущих версиях React Navigation существовала возможность использования screenProps
для обмена данными между экранами. В текущей версии React Navigation рекомендуется использовать React Context для совместного использования данных различными экранами.
Чтобы избежать циклической зависимости, вам нужно создать новый файл FriendsContext
:
- nano FriendsContext.js
Экспортируйте FriendsContext
:
import React from 'react';
export const FriendsContext = React.createContext();
Откройте App.js
:
- nano App.js
Импортируйте FriendsContext
в файл:
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { FriendsContext } from './FriendsContext';
import Home from './Home';
import Friends from './Friends';
const Stack = createStackNavigator();
class App extends React.Component {
// ...
render() {
return (
<FriendsContext.Provider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen
name="Friends"
component={Friends}
/>
</Stack.Navigator>
</NavigationContainer>
</FriendsContext.Provider>
);
}
}
// ...
Данный код определяет FriendsContext
в качестве нового объекта типа Context
и оборачивает NavigationContainer
в компонент Context.Provider
, чтобы любые дочерние элементы в дереве компонента могли подписаться на изменения контекста.
Так как вы больше не используете View
или Text
, вы можете удалить эти импорты из react-native
.
Вы должны будете предоставить элемент value
, чтобы сделать данные доступными потребителям:
// ...
class App extends React.Component {
// ...
render() {
return (
<FriendsContext.Provider
value={
{
currentFriends: this.state.currentFriends,
possibleFriends: this.state.possibleFriends,
addFriend: this.addFriend
}
}
>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen
name="Friends"
component={Friends}
/>
</Stack.Navigator>
</NavigationContainer>
</FriendsContext.Provider>
);
}
}
// ...
Это позволит HomeScreen
и FriendsScreen
ссылаться на любые изменения в контексте для currentFriends
и possibleFriends
.
Теперь вы можете поработать над ссылками на контекст в ваших экранах.
FriendsContext
на экран HomeScreen
В этом шаге вы настроите отображения текущего количества друзей в приложении.
Откройте файл HomeScreen.js
:
- nano HomeScreen.js
Импортируйте FriendsContext
в файл:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class HomeScreen extends React.Component {
// ...
}
HomeScreen.contextType = FriendsContext;
// ...
Данный код определяет Class.contextType
. Теперь вы можете получить доступ к контексту на ваших экранах.
Например, давайте заставим ваш экран HomeScreen
отображать значение текущих друзей currentFriends
для вас:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have { this.context.currentFriends.length } friends!</Text>
<Button
title="Add some friends"
onPress={() =>
this.props.navigation.navigate('Friends')
}
/>
</View>
);
}
}
HomeScreen.contextType = FriendsContext;
// ...
Если снова открыть приложение в эмуляторе и перейти на экран HomeScreen
, вы увидите сообщение: You have 0 friends!.
FriendsContext
на экран FriendsScreen
В этом шаге мы настроим отображение возможных друзей в приложении и предоставив кнопки для добавления возможных друзей в список текущих друзей.
Затем откройте файл FriendsScreen.js
:
- nano FriendsScreen.js
Импортируйте FriendsContext
в файл:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class FriendsScreen extends React.Component {
// ...
}
FriendsScreen.contextType = FriendsContext;
// ...
Данный код определяет Class.contextType
.
Теперь создайте кнопку для добавления друзей в файле FriendsScreen.js
:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class Friends extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
{
this.context.possibleFriends.map((friend, index) => (
<Button
key={ friend }
title={ `Add ${ friend }` }
onPress={() =>
this.context.addFriend(index)
}
/>
))
}
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
FriendsScreen.contextType = FriendsContext;
// ...
Если вы снова запустите приложение в эмуляторе и перейдете на экран FriendsScreen
, то увидите список друзей, которых можно добавить к текущим друзьям.
Если вы перейдете на экран FriendsScreen
и нажмете кнопку для добавления друзей, то увидите, что список возможных друзей possibleFriends
сократился. Если же перейти на экран HomeScreen
, то можно увидеть, как выросло количество текущих друзей.
Теперь вы можете переходить между экранами и организовать обмен данными между ними.
В этом руководстве вы создали образец приложения React Native с несколькими экранами. Используя React Navigation, вы реализовали способ навигации между экранами. Используя React Context, вы разработали способ обмена данными между экранами.
Полный исходный код этого проекта доступен на GitHub.
Если вы хотите глубже погрузиться в изучение React Navigation, ознакомьтесь с документацией.
React Navigation — это не единственное решение для маршрутизации и навигации. Существует также React Native Navigation, React Native Router Flux и React Router Native.
Если вы хотите узнать больше о React, почитайте нашу серию «Программирование на React.js» или посмотрите страницу тем React, где вы найдете упражнения и программные проекты.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Добрый день, у вас ошибка в статье. В группе “Добавление контекста FriendsContext на экран FriendsScreen”. Ранее создавались скрины FriendsScreen и HomeScreen, но в коде App.js в импортах и Stack.Screen component стоят просто Friends и Home, нужно их заменить на FriendsScreen и HomeScreen, иначе приложение будет выдавать ошибку: ReferenceError: Can’t find variable: Home. В остальном статья очень понятная, большое вам спасибо за труды!