介绍
Redux是 JavaScript 应用程序的可预测状态容器。如果您对 Redux 不熟悉,我们建议您查看我们对 Redux 的介绍。
在本文中,您将学习如何在 React Native 应用程序中使用 Redux 持久化用户数据。该应用程序是一个模拟社交网络,HomeScreen
显示已连接好友的数量,并FriendsScreen
显示要添加的潜在好友列表。您将使用 Redux 在两个屏幕之间共享状态。
先决条件
要完成本教程,您需要:
- Node.js 的本地开发环境。遵循如何安装 Node.js 并创建本地开发环境。
- 熟悉设置环境以创建新的 React Native 项目并使用 iOS 或 Android 模拟器可能会有所帮助。
本教程基于如何在 React Native 中使用带有 React 导航的路由中涵盖的主题。建议您阅读本教程以了解有关该项目如何工作的更多背景信息,但这不是必需的。
本教程已通过 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
本教程将使用如何在 React Native 中使用带有 React 导航的路由中的代码的修改版本。首先,克隆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 是一个纯函数,它接受前一个状态和一个动作作为参数并返回一个新状态。reducer 有助于在整个应用程序中保持朋友的当前状态随着它的变化而更新。
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
商店的信息负载。
Actions 有一个type和一个可选的payload。在本教程中,类型将为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
将朋友添加到当前朋友的数组中。进行更改后,状态会更新。
现在,你有一个减速器和一个动作。您需要将 reducer 应用到您的应用程序中。
第 4 步 – 将 Reducer 添加到应用程序
您需要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>
)
}
}
现在friends
可以在您的应用程序中访问,但您仍然需要将它们添加到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
,您将看到来自减速器的所有可能的朋友。
最后,将新的 ReduxaddFriend
操作添加到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
action
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 做更多事情,从保持数据与数据库同步,到身份验证和跟踪用户权限。
如果您想了解有关 React 的更多信息,请查看我们的How To Code in React.js系列,或查看我们的 React 主题页面以获取练习和编程项目。