在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
然后,在项目中安装 redux
和 react-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
导入 Provider
、createStore
和 friendsReducer
:
应用程序.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'; // ...
添加并用 createStore
和 Provider
替换突出显示的代码:
应用程序.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
可以在您的应用程序中访问,但您仍然需要将它们添加到 HomeScreen
和 FriendsScreen
。
第 5 步 — 将 Redux 添加到屏幕
在此步骤中,您将使用 mapStateToProps
功能使屏幕可以访问 friends
。 该函数将state
从FriendsReducer
映射到两个画面中的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; } };
这使得应用程序不那么脆弱。 在开发应用程序时,您应该注意合并代码和避免重复自己的机会。
结论
在本教程中,您介绍了 redux
、reducers
、actions
和可扩展的数据管理。
您可以使用 Redux 做更多的事情,从保持数据与数据库同步,到身份验证和跟踪用户权限。
本教程的完整 源代码可在 GitHub 上获得。
如果您想了解有关 React 的更多信息,请查看我们的 如何在 React.js 中编码,或查看 我们的 React 主题页面 以了解练习和编程项目。