Поиск по сайту:

Введение в использование 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:

  1. git clone https://github.com/do-community/MySocialNetwork.git

Затем перейдите в каталог проекта:

  1. cd MySocialNetwork

Измените ветку git на redux-starter:

  1. git checkout redux-starter

Затем установите зависимости проекта:

  1. npm install

Затем установите в проект библиотеки redux и react-redux:

  1. npm install redux@4.0.5 react-redux@7.2.1

Теперь ваш проект настроен, и ваши зависимости установлены.

Шаг 2 — Создание редуктора

Чтобы подключить Redux к вашему приложению, вам нужно создать reducer и action.

Во-первых, вы создадите редьюсер друзей. Редуктор — это чистая функция, которая принимает в качестве аргументов предыдущее состояние и действие и возвращает новое состояние. Редуктор играет важную роль в обновлении текущего состояния друзей в приложении по мере его изменения.

Создайте файл FriendsReducer.js на корневом уровне проекта:

  1. 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 на корневом уровне проекта:

  1. nano FriendsActions.js

Добавьте addFriend:

export const addFriend = friendsIndex => (
  {
    type: 'ADD_FRIEND',
    payload: friendsIndex,
  }
);

Когда пользователь нажимает на друга, этот код извлекает friendsIndex из массива friends.possible. Теперь вам нужно будет использовать этот индекс, чтобы переместить этого друга в массив friends.current.

Пересмотрите FriendsReducer.js:

  1. 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:

  1. 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:

  1. 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:

  1. 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 на корневом уровне:

  1. 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:

  1. 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 с упражнениями и проектами по программированию.