Введение в использование Redux в приложении React Native
Введение
наше введение в Redux.
В этой статье вы узнаете, как сохранять пользовательские данные с помощью Redux в приложении React Native. Приложение представляет собой имитацию социальной сети с HomeScreen
, отображающим количество подключенных друзей, и FriendsScreen
, отображающим список потенциальных друзей для добавления. Вы будете использовать Redux для обмена состоянием между двумя экранами.
Предпосылки
Для выполнения этого урока вам понадобится:
- Локальная среда разработки для Node.js. Следуйте инструкциям по установке Node.js и созданию локальной среды разработки.
- Знакомство с настройкой среды для создания нового проекта React Native и использованием симуляторов iOS или Android может оказаться полезным.
Это руководство основано на темах, рассмотренных в разделе «Как использовать маршрутизацию с навигацией React в React Native». Рекомендуется прочитать это руководство для получения дополнительной информации о том, как работает проект, но это не обязательно.
Это руководство было проверено с помощью 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, redux
v4.0.5 и react- редукс
v7.2.1.
Шаг 1 — Настройка проекта и установка Redux
В этом руководстве будет использоваться модифицированная версия кода в MySocialNetwork
:
- git clone https://github.com/do-community/MySocialNetwork.git
Затем перейдите в каталог проекта:
- cd MySocialNetwork
Измените ветку git на redux-starter
:
- git checkout redux-starter
Затем установите зависимости проекта:
- npm install
Затем установите в проект библиотеки redux
и react-redux
:
- npm install redux@4.0.5 react-redux@7.2.1
Теперь ваш проект настроен, и ваши зависимости установлены.
Шаг 2 — Создание редуктора
Чтобы подключить Redux к вашему приложению, вам нужно создать reducer и action.
Во-первых, вы создадите редьюсер друзей. Редуктор — это чистая функция, которая принимает в качестве аргументов предыдущее состояние и действие и возвращает новое состояние. Редуктор играет важную роль в обновлении текущего состояния друзей в приложении по мере его изменения.
Создайте файл FriendsReducer.js
на корневом уровне проекта:
- nano FriendsReducer.js
Добавьте следующий код:
import { combineReducers } from 'redux';
const INITIAL_STATE = {
current: [],
possible: [
'Alice',
'Bob',
'Sammy',
],
};
const friendsReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
default:
return state
}
};
export default combineReducers({
friends: friendsReducer
});
В этом файле вы создаете переменную INITIAL_STATE
с возможными друзьями для добавления в вашу социальную сеть. Затем вы экспортируете friendsReducer
как свойство с именем friends
.
Когда ваш редуктор установлен, вам понадобится способ добавления друзей.
Шаг 3 — Создание действия
Действия — это объекты JavaScript, представляющие полезные данные, которые отправляют данные из вашего приложения в хранилище Redux
.
Действия имеют тип и необязательную полезную нагрузку. В этом руководстве типом будет ADD_FRIEND
, а полезной нагрузкой будет индекс массива друга, которого вы добавляете в массив друзей current
.
Создайте файл FriendsActions.js
на корневом уровне проекта:
- nano FriendsActions.js
Добавьте addFriend
:
export const addFriend = friendsIndex => (
{
type: 'ADD_FRIEND',
payload: friendsIndex,
}
);
Когда пользователь нажимает на друга, этот код извлекает friendsIndex
из массива friends.possible
. Теперь вам нужно будет использовать этот индекс, чтобы переместить этого друга в массив friends.current
.
Пересмотрите FriendsReducer.js
:
- nano FriendsReducer.js
Добавьте ADD_FRIEND
:
// ...
const friendsReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case 'ADD_FRIEND':
// Pulls current and possible out of previous state
// We do not want to alter state directly in case
// another action is altering it at the same time
const {
current,
possible,
} = state;
// Pull friend out of friends.possible
// Note that action.payload === friendIndex
const addedFriend = possible.splice(action.payload, 1);
// And put friend in friends.current
current.push(addedFriend);
// Finally, update the redux state
const newState = { current, possible };
return newState;
default:
return state
}
};
// ...
Этот код выводит текущих и возможных друзей из предыдущего состояния. Array.splice()
извлекает друга из массива возможных друзей. Array.push
добавляет друга в массив текущих друзей. После внесения изменений состояние обновляется.
Теперь у вас есть редьюсер и действие. Вам нужно будет применить редуктор к вашему приложению.
Шаг 4 — Добавление редюсера в приложение
Вам нужно будет указать состояние friends
вашего приложения с помощью компонента React Redux Provider
.
Откройте App.js
:
- nano App.js
Импортируйте Provider
, createStore
и friendsReducer
:
import 'react-native-gesture-handler';
import React from 'react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import friendsReducer from './FriendsReducer';
import HomeScreen from './HomeScreen';
import FriendsScreen from './FriendsScreen';
// ...
Добавьте и замените выделенный код на createStore
и Provider
:
// ...
const store = createStore(friendsReducer);
class App extends React.Component {
// ...
render() {
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Friends"
component={FriendsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
)
}
}
Теперь друзья
доступны в вашем приложении, но вам все равно нужно добавить их на HomeScreen
и FriendsScreen
.
Шаг 5 — Добавление Redux на экраны
На этом шаге вы сделаете friends
доступными для ваших экранов с помощью функции mapStateToProps
. Эта функция сопоставляет state
от FriendsReducer
с props
на двух экранах.
Начнем с HomeScreen.js
. Откройте файл HomeScreen.js
:
- nano HomeScreen.js
Добавьте и замените выделенные строки кода в HomeScreen.js
:
import React from 'react';
import { connect } from 'react-redux';
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>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
const mapStateToProps = (state) => {
const { friends } = state
return { friends }
};
export default connect(mapStateToProps)(HomeScreen);
Это изменение кода добавляет react-redux
и делает friends
доступными для HomeScreen
.
Затем добавьте значения для текущих друзей (this.props.friends.current
):
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have { this.props.friends.current.length } friends.</Text>
<Button
title="Add some friends"
onPress={() =>
this.props.navigation.navigate('Friends')
}
/>
</View>
);
}
}
Ваш HomeScreen
теперь будет отображать количество текущих друзей. Теперь вы можете перейти к FriendsScreen
.
Откройте FriendsScreen.js
:
- nano FriendsScreen.js
Добавьте и замените выделенные строки кода в FriendsScreen.js
:
import React from 'react';
import { connect } from 'react-redux';
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>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
const mapStateToProps = (state) => {
const { friends } = state
return { friends }
};
export default connect(mapStateToProps)(FriendsScreen);
Это изменение кода добавляет react-redux
и делает friends
доступными для FriendsScreen
.
Добавьте значения для возможных друзей (props.friends.possible
):
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
{
this.props.friends.possible.map((friend, index) => (
<Button
key={ friend }
title={ `Add ${ friend }` }
/>
))
}
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
Теперь, когда вы перейдете к FriendsScreen
, вы увидите всех возможных друзей из редуктора.
Наконец, добавьте новое действие Redux addFriend
в FriendsScreen.js
:
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { StyleSheet, Text, View, Button } from 'react-native';
import { addFriend } from './FriendsActions';
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
{
this.props.friends.possible.map((friend, index) => (
<Button
key={ friend }
title={ `Add ${ friend }` }
onPress={() =>
this.props.addFriend(index)
}
/>
))
}
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
// ...
const mapDispatchToProps = dispatch => (
bindActionCreators({
addFriend,
}, dispatch)
);
export default connect(mapStateToProps, mapDispatchToProps)(FriendsScreen);
Давайте добавим двух друзей в социальную сеть и вернемся на HomeScreen
, чтобы увидеть, сколько текущих друзей есть у пользователя:
При этом вы переместили всю логику из App.js
в Redux
, что делает ваше приложение намного более гибким, особенно когда вы добавляете больше страниц и функций, таких как аутентификация и база данных. интеграция.
Прежде чем мы закончим, давайте очистим код.
Шаг 6 — Очистка
Теперь, когда вы используете Redux
, вам больше не понадобятся реквизиты, которые вы передавали из App.js
.
Вы можете пойти дальше, сохранив типы action
в отдельном файле.
Вы используете строку ADD_FRIEND
в двух местах: в action
и в дружественном reducer
. Это опасно, потому что если вы измените строку в одном месте, а не в другом, вы можете сломать ваше приложение. По мере роста вашего приложения имеет смысл хранить все эти типы action
в файле с именем types.js
.
Создайте файл types.js
на корневом уровне:
- nano types.js
Добавьте следующий код:
export const ADD_FRIEND = 'ADD_FRIEND';
Затем снова откройте FriendsActions.js
, чтобы использовать новый ADD_FRIEND
:
nano FriendsActions.js
Измените цитируемый ADD_FRIEND
на переменную ADD_FRIEND
в вашем действии
:
import { ADD_FRIEND } from './types';
export const addFriend = friendsIndex => (
{
type: ADD_FRIEND,
payload: friendsIndex,
}
);
Затем снова откройте FriendsReducer.js
, чтобы также использовать новый ADD_FRIEND
:
- nano FriendsReducer.js
Измените цитируемый ADD_FRIEND
на переменную ADD_FRIEND
в вашем reducer
:
import { combineReducers } from 'redux';
import { ADD_FRIEND } from './types';
// ...
const friendsReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case ADD_FRIEND:
// ...
default:
return state;
}
};
Это делает приложение менее уязвимым. При разработке своих приложений вы должны знать о возможностях консолидации кода и избегать повторений.
Заключение
В этом руководстве вы рассмотрели redux
, reducers
, actions
и управление масштабируемыми данными.
С Redux можно делать гораздо больше вещей, от синхронизации данных с базой данных до аутентификации и отслеживания разрешений пользователей.
Полный исходный код этого руководства доступен на GitHub.
Если вы хотите узнать больше о React, загляните на нашу страницу темы React с упражнениями и проектами по программированию.