Redux 和 Context API 与 React Native App:简介、用例、实施和比较
如果您有 Javascript 背景,那么您可能熟悉术语Redux 和 Context API。并且可能,您可能遇到过很多关于哪个更好的博客——Redux 与 Context API。我假设相同,除非我意识到它不是!
在阅读了一堆博客之后,我总结了这两种工具的用途以及它们之间的区别。如果您还不知道,请不要担心,本教程将通过一个基本的演示示例帮助您了解这两种工具的用例。在这里,我们将使用这两种方法构建一个应用程序并讨论它们。
那我们开始吧!
教程目标
了解 Redux 和上下文 API
比较 Redux 和 Context API 的工作
探索 Redux 和 Context API 的目的和用例
使用 Redux 和 Context API 方法的演示应用程序
Redux:简介和构建块
根据文件-
Redux 是一种模式和库,用于使用称为“动作”的事件来管理和更新应用程序状态。它作为需要在整个应用程序中使用的状态的集中存储,其规则确保状态只能以可预测的方式更新。
文档中明确提到 redux 是为了“管理状态”,理解状态是如何更新的。
Redux 的用例
如文档中所述,redux 的主要目标是管理和跟踪状态。
将状态管理逻辑与用户界面层分开
更快的逻辑调试
Redux 主要用于集中管理 React 应用程序的状态,可以在应用程序的任何位置访问状态。从技术上讲,Redux 的概念是基于 Flux 架构的,这个概念并不局限于 React 应用程序;也有不同技术的实现(例如 Angular 的 NgRx)。但是 Redux 特别是用 React 实现的。
需要的包裹
redux :用于createStore()、combineReducer()等函数。
react-redux :用于connect()等功能。
Redux 的构建块
它主要由四个构建块组成:
1. Reducer:这些是将状态和动作作为参数传入的函数。它在返回更改值的开关案例中包含“action.type” 。它可选择接受有效负载(通常在称为reducers.js 的单独文件中创建)
2. Store:Store是所有数据的集合。您可以将其传递给提供商。
3. Provider:接受 store 作为参数的 React 组件(通常在index.js中创建)
4. 动作:向调度器提供/返回动作类型和有效负载的函数,调度器将进一步调用相应的 reducer(通常在称为actions.js的单独文件中创建)
上下文 API:简介和构建块
React 文档将 context API 解释为 -
Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动传递 props。
在典型的 React 应用程序中,数据通过 props 自上而下(父到子)传递,但对于应用程序中许多组件所需的某些类型的 props(例如语言环境首选项、UI 主题),这种使用可能很麻烦。Context 提供了一种在组件之间共享这些值的方法,而无需显式地通过树的每个级别传递 prop。
如果您可以观察“传递”和“共享”值的文档状态上下文,而没有提及“管理状态”
上下文 API 的用例
使用上下文 API 的主要目的是避免“prop drilling”——在每个级别传递 prop。它更像是用于将值从一端传递到另一端的管道。
上下文 API 提供了通过组件树传递数据的最简单方法,这样您就不必在每个级别手动传递道具。例如,假设我们有一个由 A、B、C 和 D 组件组成的组件树。现在你需要将 props 从 A 传递到 D,而不是传递它 A > B > C > D,即传递给每个组件,在上下文的帮助下你可以直接传递到 A > D。
现在,许多博客都提到 Context API 是 Redux 的最佳替代品,因为它是内置的,您不必为此安装依赖项。这是真的吗——Context API 可以取代 Redux 吗?我们将在下一节中对此进行讨论。请继续关注探索!
上下文 API 的构建块
我们可以将上下文 API 分为三个块:
1. 上下文:使用将默认值作为第一个参数的createContext()函数。在这里传递 Javascript 对象是可选的。您可以在您的应用程序中实现多个上下文。
2.Provider:Provider创建context后,提供访问context的能力。它提供函数和数据以将值进一步传递给组件。
3. Consumer:Consumer 允许访问 Provider 包装的子组件的值。它有两种类型——
Context.Consumer: Context.Consumer可用于功能组件和基于类的组件。但是,通过这种方法,上下文只能在渲染方法中访问。
静态上下文类型: 静态上下文类型只能用于基于类的组件。
Redux 和上下文 API 示例
下面的示例基于计数器。初始值为 0,它有两个按钮来递增和递减该值。
在主父计数器组件内,将有三个子组件-
• 一个用于更改计数器值
• 每个按钮两个。
Context 和 Redux 方法的初始设置是相同的。
您是否正在为在 Context 和 Redux 方法之间做出选择并在您的应用程序中实施它而苦恼?与最好的React Native App Development Company
取得联系,他们拥有具有此类专业知识的开发人员,可以轻松无痛地实施!
创建 React Native 应用程序
最初,使用以下命令创建一个 React Native 应用程序
反应本机初始化 CounterDemo
Redux 方法:如何在 React Native App 中实现 Redux?
安装 Redux 所需的依赖项
npm 安装 redux --savenpm 安装 react-redux --save
Redux 商店设置
我们将在App.js文件中创建我们的商店。
// 应用程序.js
import React, { Component } from 'react';从'react-redux'导入{Provider};从'redux'导入{createStore};从 './reducers/index.js' 导入 totalReducers;从'./components/counters'导入计数器;
const store = createStore(totalReducers);
导出默认类 App extends Component{
使成为(){
返回(
);
}}
这里我们导入总减速器从减速器文件夹。
创建商店()函数接受一个参数作为总减速器对象并生成商店。
Provider 组件确保商店在整个应用程序中可用。
减速器设置
减速器返回应用程序所需的数据。在此演示中,reducer 将返回更新后的计数器值。这是reducers 文件夹中的counterReducer.js文件。
// 减速器/counterReducer.js
让计数= 0;
导出默认值(状态=计数,动作)=> {
开关(动作类型){
案例“增量”:
计数++
休息;
案例“减量”:
数数 -
休息;
默认:
数数;
}
返回计数; }
解释
上面定义的 reducer 将始终返回计数值。
增量和减量是将更新值的操作类型,如上所示。
我们将在 reducers 文件夹内的 index.js 文件中组合所有的 reducer。
// reducers/index.js
从'redux'导入{combineReducers};从 './counterReducer' 导入 counterReducer;
const totalReducers= combineReducers({
计数:counterReducer,});
导出默认的 totalReducers;
解释
在这里,我们将把所有的 reducer 组合起来作为Redux 库的combineReducers()函数的参数。
动作设置
创建两个动作:增量和减量。
// 动作/index.js
导出函数增量(){
返回{
类型:“增量”
};
}
导出函数递减(){
返回{
类型:“递减”
};}
界面组件
我们将只创建一个称为计数器组件的组件。为了使用 reducer 和 action,我们必须实现这些功能:
mapStateToProps() – 它只是接受你的 reducer 数据,并将其转换成一个简单可用的 prop。在this.props.data的帮助下,我们将在组件中使用数据作为道具。
函数 mapStateToProps(状态){
返回{
计数:state.count
};}
注意:请记住我们是如何在 combineReducers 函数中为 reducer 分配名称的,因为我们必须使用相同的名称来调用各个 reducer。
mapDispatchToProps() – 它接受你的动作,并将它们转换成一个简单的可用道具。
函数 mapDispatchToProps(调度){
返回 bindActionCreators({增量,减量},分派)}
注意:bindActionCreators函数只是将我们的动作组合到一个对象中。
转向管理用户界面的组件。
// 组件/counter.js
类计数器扩展组件{
构造函数(道具){
超级(道具);
}
使成为() {
返回 (
{'Redux 方法'}
{this.props.count}this.props.increment()}> 增量+this.props.decrement()}> 递减 -
);
}}
函数 mapStateToProps(状态){
返回 {
计数:state.count,
};}
函数 mapDispatchToProps(调度){
返回 bindActionCreators({increment, decrement}, dispatch);}
导出默认连接(mapStateToProps,mapDispatchToProps)(计数器);
要设置组件样式,您可以使用以下代码
const styles = StyleSheet.create({
主容器:{
弹性:1,
justifyContent: '中心',
alignItems: '中心',
},
柜台号码:{
字体大小:35,
fontWeight: '粗体',
},
按钮容器:{
flexDirection: '行',
},
按钮样式:{
背景颜色:'绿色',
边框宽度:1,
身高:30,
宽度:'25%',
边界半径:5,
justifyContent: '中心',
alignItems: '中心',
},});
整理起来
到目前为止,我们已经完成了计数器演示的 redux 设置、逻辑和用户界面。现在,只剩下一个简单的步骤——将我们的 App 文件导入到我们的 index.js 文件中。
// 索引.js
从 'react-native' 导入 {AppRegistry};从'./src/App.js'导入应用程序;从 './app.json' 导入 {name as appName};
AppRegistry.registerComponent(appName, () => App);
Git 回购链接:https://github.com/sunil-bacancy/CounterDemo
Context API 方法:如何在 React Native App 中实现 Context API?
由于上下文 API 是内置功能,我们不需要安装第三方依赖项。
文件夹结构
在您的应用程序的根目录下创建一个文件夹src 。在src文件夹中,我们必须创建 3 个文件夹,分别是reducers、components、state和一个文件App.js。
减速器设置
就像 Redux 一样,使用 Context API 声明 reducer。
// 减速器/globalReducer.js
export default countReducer = (state, action) => {
开关(动作类型){
案例“增量”:
返回{
...状态,
计数器:state.counter + 1,
}
案例“减量”:
返回{
...状态,
计数器:state.counter - 1,
}
默认:
返回{
状态
}
} }
创建上下文
使用createContext()创建上下文并将初始状态作为参数传递。您也可以在不传递参数的情况下进行定义。
定义一个将通过 Provider 传递数据的函数。
useReducer()将采用具有默认状态的 reducer,然后返回更新后的值并分派该函数。
在 Provider 函数中,使用带参数的useReducer() - reducer 和初始状态。返回和调度状态稍后作为值传递给提供者。
// 状态/globalState.js
从“反应”中导入反应,{createContext,useReducer};从 '../reducers/globalReducer' 导入 countReducer;
const 初始状态 = {
计数器:0}
export const GlobalContext = createContext(initialState);
导出默认 GlobalProvider = ({children}) => {
const [state, dispatch] = useReducer(countReducer, initialState);
返回(
{孩子们}
)}
提供上下文
创建上下文后,我们需要提供上下文,以便在子组件中可以访问它。为此,您需要将其包装在 Provider 中。
// 源代码/App.js
import React, { Component } from 'react';从“./state/globalState”导入 GlobalProvider;从'./components/counter'导入计数器;
导出默认类 App 扩展组件 {
使成为(){
返回 (
)
}}
消费语境
使用 useContext() 在各个子组件中使用上下文。
// 组件/counter.js
从'react'导入React,{Component,useContext};import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';从 '../state/globalState' 导入 {GlobalContext};
常量计数器 = () => {
const {state} = useContext(GlobalContext);
const {dispatch} = useContext(GlobalContext);
返回(
{'上下文 API 方法'}
{ 状态. 计数器 }
调度({类型:“增量”})}
>
增量+
调度({类型:“递减”})}
>
递减 -
)}
导出默认计数器;
要为您的组件设置样式,您可以使用以下代码。
const styles = StyleSheet.create({
主容器:{
弹性:1,
justifyContent: '中心',
alignItems: '中心'
},
柜台号码:{
字体大小:35,
fontWeight: '粗体'
},
按钮容器:{
flexDirection: '行'
},
按钮样式:{
背景颜色:'绿色',
边框宽度:1,
身高:30,
宽度:'25%',
边界半径:5,
justifyContent: '中心',
alignItems: '中心',
},})
Git 回购链接:https://github.com/sunil-bacancy/CounterContextDemo
Redux 和 Context API:比较
终极版
存储和管理值
在 React 组件之外工作
避免螺旋钻
通过调度一个动作,可以更新值
提供 DevTools 以显示操作和状态值的历史记录
允许应用程序代码通过中间件触发副作用
上下文API
不用于存储或管理值
仅适用于 React 组件
传递单个值,可以是对象、基元、类等。
避免螺旋钻
为提供者和消费者提供当前上下文值,但不显示值更改方式的任何历史记录。
排除副作用机制——专用于组件渲染
结论
我希望本教程能帮助您了解 Context 和 Redux 的不同之处。此外,尝试实现这两种方法并使用代码进行更深入的挖掘。对于更多此类 React Native 教程,我们有一个React Native 教程页面,其中包含带有 github 源的分步指南。
我可以理解为一个复杂的应用程序组织和管理全局存储有多么困难,以及在您的应用程序中实现 Context API 需要多么精确。如果您有一个庞大而复杂的项目并且想要实施 Redux 或 Context API,请随时联系我们并聘请React Native 开发人员。