在ReactNative应用程序中使用Redux简介

来自菜鸟教程
跳转至:导航、​搜索

介绍

Redux 是 JavaScript 应用程序的可预测状态容器。 如果您对 Redux 不熟悉,我们建议您查看 我们对 Redux 的介绍。

在本文中,您将学习如何在 React Native 应用程序中使用 Redux 持久化用户数据。 该应用程序是一个模拟社交网络,其中 HomeScreen 显示已连接朋友的数量,FriendsScreen 显示要添加的潜在朋友列表。 您将使用 Redux 在两个屏幕之间共享状态。

先决条件

要完成本教程,您需要:

  • Node.js 的本地开发环境。 关注【X7X】如何安装Node.js并创建本地开发环境【X76X】。
  • 熟悉设置环境以创建新的 React Native 项目并使用 iOS 或 Android 模拟器可能会有所帮助。

本教程建立在 How To Use Routing with React Native in React Navigation 中涵盖的主题之上。 建议您阅读本教程以了解有关项目如何工作的更多背景信息,但这不是必需的。

本教程已使用 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-redux v7.2.1。

第 1 步 — 设置项目并安装 Redux

本教程将使用 How To Use Routing with React Navigation in React Native 中代码的修改版本。 首先,克隆 MySocialNetwork

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

然后,导航到项目目录:

cd MySocialNetwork

将 git 分支更改为 redux-starter

git checkout redux-starter

接下来,安装项目依赖项:

npm install

然后,在项目中安装 reduxreact-redux 库:

npm install redux@4.0.5 react-redux@7.2.1

您的项目现已设置完毕,并且您的依赖项已安装。

第 2 步——创建一个 Reducer

要将 Redux 连接到您的应用程序,您需要创建一个 reducer 和一个 action

首先,您将创建一个朋友减速器。 reducer 是一个纯函数,它将先前的 state 和一个动作作为参数并返回一个新状态。 reducer 有助于在整个应用程序更改时保持朋友的当前状态更新。

在项目的根目录下创建 FriendsReducer.js 文件:

nano FriendsReducer.js

添加以下代码:

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 存储的信息负载。

Actions 有一个 type 和一个可选的 payload。 在本教程中,类型将为 ADD_FRIEND,有效负载将是您要添加到 current 好友数组中的好友的数组索引。

在项目的根目录下创建 FriendsActions.js 文件:

nano FriendsActions.js

添加addFriend

FriendsActions.js

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

当用户点击好友时,此代码将从 friends.possible 数组中检索 friendsIndex。 现在您需要使用该索引将该朋友移动到 friends.current 数组中。

重温FriendsReducer.js

nano FriendsReducer.js

添加ADD_FRIEND

FriendsReducer.js

// ...

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 将好友添加到当前好友数组中。 进行更改后,状态将更新。

现在,你有了一个 reducer 和一个 action。 您需要将减速器应用于您的应用程序。

第 4 步 — 将 Reducer 添加到应用程序

您需要使用 React Redux 的 Provider 组件 提供应用程序的 friends 状态。

打开App.js

nano App.js

导入 ProvidercreateStorefriendsReducer

应用程序.js

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';

// ...

添加并用 createStoreProvider 替换突出显示的代码:

应用程序.js

// ...

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>
    )
  }
}

现在 friends 可以在您的应用程序中访问,但您仍然需要将它们添加到 HomeScreenFriendsScreen

第 5 步 — 将 Redux 添加到屏幕

在此步骤中,您将使用 mapStateToProps 功能使屏幕可以访问 friends。 该函数将stateFriendsReducer映射到两个画面中的props

让我们从 HomeScreen.js 开始。 打开HomeScreen.js文件:

nano HomeScreen.js

添加和替换 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):

HomeScreen.js

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 中突出显示的代码行:

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

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

添加以下代码:

类型.js

export const ADD_FRIEND = 'ADD_FRIEND';

然后,重新访问 FriendsActions.js 以使用新的 ADD_FRIEND

nano FriendsActions.js

将引用的 'ADD_FRIEND' 更改为 action 中的变量 ADD_FRIEND

FriendsActions.js

import { ADD_FRIEND } from './types';

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

然后,重新访问 FriendsReducer.js 以使用新的 ADD_FRIEND

nano FriendsReducer.js

将引用的 'ADD_FRIEND' 更改为 reducer 中的变量 ADD_FRIEND

FriendsReducer.js

import { combineReducers } from 'redux';
import { ADD_FRIEND } from './types';

// ...

const friendsReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case ADD_FRIEND:
      // ...

    default:
      return state;
  }
};

这使得应用程序不那么脆弱。 在开发应用程序时,您应该注意合并代码和避免重复自己的机会。

结论

在本教程中,您介绍了 reduxreducersactions 和可扩展的数据管理。

您可以使用 Redux 做更多的事情,从保持数据与数据库同步,到身份验证和跟踪用户权限。

本教程的完整 源代码可在 GitHub 上获得。

如果您想了解有关 React 的更多信息,请查看我们的 如何在 React.js 中编码,或查看 我们的 React 主题页面 以了解练习和编程项目。