Redux 和 Context API 与 React Native App:简介、用例、实施和比较

言鼎科技 2023-07-01 194

如果您有 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 实现的。

你可能喜欢阅读:

如何在 React Native 应用程序中使用 Redux 和 React Hooks

需要的包裹

  • 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 开发人员

言鼎科技

The End