Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ReactNative之Redux详解

ReactNative之Redux详解

作者头像
lizelu
发布于 2020-06-19 10:19:55
发布于 2020-06-19 10:19:55
1.5K00
代码可运行
举报
文章被收录于专栏:青玉伏案青玉伏案
运行总次数:0
代码可运行

用redux有一段时间了,感觉还是有必要把其相关的知识点系统的总结一下的,毕竟好记性不如烂笔头。上篇博客更新了关于《ES6中的迭代器、Generator函数以及Generator函数的异步操作》的内容,该内容时saga的基础,稍后会总结saga相关知识点。循序渐进,本篇博客主要总结的是Redux相关的内容,然后下篇博客打算总结一下react-redux, 以及redux-thunk、redux-saga中间件

一、Redux与iOS中的Notification的比较

Redux 的功能和作用就是让State管理更为集中,因为在redux中所有的状态都是存储在Store中的,而在页面的各个模块中都可以去访问和修改Store中存储的状态值。从这一点来看,redux可以很好的解决一个页面中多个模块间的状态共享的问题。

Redux这框架理解起来是比较简单的,这个框架本身也是比较小的,涉及的API也非常少。虽然小,但小而精。使用起来还是满顺手的,大道至简。下方是Redux中的几个关键的词及对应的功能,理解完下方的几个关键词,Redux这个框架也就大概了解了。

  • Store : 从字面意思看,Store是存储、储存的意思,在 Redux 中,把相关的状态存储在了Store中,在Redux中Store可以看做是一个单例对象。并且Store中提供了一些API来操作这些状态,如下所示:
    • getState : 该方法用来获取Store中当前存储的状态值。
    • subscribe(listener回调方法): 用来监听Store中状态值的改变,状态值改变后会执行相关回调方法。
    • dispatch (action) : 该方法用来修改Store中存储的状态值,而Action就是一个普通的对象,其中可以携带一些修改特定状态时的一些信息。
  • Action: 上面也说了,而Action就是一个普通的对象,其中可以携带一些修改特定状态时的一些信息,被用来作为dispatch()方法的参数的。起到了媒介的作用,Action本身会携带一些信息,便于状态的修改。
  • Reducer: Reducer本质上是一个 方法集合的称呼,而这些方法的入参是 当前的State和Action,出参是被修改后的新的State对象,也就是说 dispatch 一个Action会执行一个Reducer。而Reducer对应方法,会根据Action携带的信息来修改State对象,并把修改后的State对象返回出去。当然返回这新的State会更新到Store中,从而会触发一系列的监听操作。

Redux的工作模式虽然是管理状态的,但是使用上个人感觉更想通知。与iOS中的Notification工作方式即为相似,下方做了一些简单的类比。下方简单的画了一个类比的图,可以从下往上看,解释如下:

  • 通知中心:最下方是通知中心,对应着iOS的 NotificationCenter,主要用来注册、派发及移除通知的,所以的通知都会经过NotificationCenter的管理。在 Redux中,这个Store就扮演着 这个NotificationCenter的角色,用来管理所有的状态。不同的时,Store中会存储各种状态。
  • 发送通知:如果要修改状态的值的话,得调用 Store中提供的 dispatch(事件派发) 方法来修改相关的状态,这个就好像 iOS中发送通知的Post方法。
  • 注册监听:而Store中的 subscribe 这个监听状态改变的方法,就类似于 Notification 中的 register方法,只有添加完监听的相关对象才能收到状态被修改的通知。
  • 通知对象:Store中的dispatch() 方法的参数 Action,就类似于 Notification 对象,用来携带通知或者状态修改的信息。
  • 执行方法:而 redux 中的 Reducer 就类似于执行通知的Selector,用来修改状态的。

二、通过加减法示例来看Redux的使用方式

下方通过一个简单的加减法程序来看一下Redux的使用方式。之前在介绍 iOS中的响应式框架 ReactiveCocoa 时写过类似的Demo,只不过今天我们用 Redux 来实现一下。

demo比较简单,就是两个加减法,输入的时候自动的修改计算的结果值。下方我们就来简单的看一下RN中如何使用Redux来实现该功能。

1、创建Store

首先创建Store,redux 专门提供了一个创建store的方法 createStore ,调用 createStore 时,我们需要把修改State的Reducer方法传进去进行关联。下方的calculateReducer是自定义的一个修改State的方法,稍后会介绍。下方代码比较简单,就是创建了一个Store,并将该对象导了出去。  

2、创建Action

创建Store后,接下来我们来创建对应的Action,下方代码就是对应的action文件中的内容。首先创建了一个 CountActionType 的对象,功能类似于枚举,其中 "ADD" 代表加法类型,"DESC" 代表减法类型。因为该示例中是在一个Reducer中处理的两个Action,所以得用 CountActionType 类型来判断派发的是哪个Action,然后做对应的操作。

然后创建了一个 addTowNumbers 方法,该方法接收了一个参数,然后返回一个Action对象,其中Action对象的类型就是 ADD。 而下方的 descTowNumbers 方法返回的也是一个Action,该Action对应的是减法操作。稍后我们会使用到该Action。

3、创建Reducer

下方的calculateReducer方法就是我们创建的Reducer, 该方法接收两个参数,一个是State对象, 一个是Action对象。我们给State对象赋了一个默认值, 这个默认值中有两个值,一个是表示加法结果的 addResult, 另一个是表示减法结果的 descResult。

Action对象中的payload对象中有两个值,及firstNumberhe和secondNumber,表示输入的两个值。而在Reducer中通过Action的Type字段来判断是做加法操作还是减法操作。如果是Add则是加法操作,将payload中的两个值相加,然后将结果赋值给 state 中的addResult。如果是Desc的话,与Add类似,只不过做的是减法操作。

在该Reducer方法中,返回的是一个计算后端新的State。State被修改后,可以通过 Store 中的 subscribe 的方法进行监听该状态的改变。

4、AddTestView的实现

定义好Store、Action、Reducer, 接下来我们就开始定义可操作的视图了。下方的AddTestView就是上面两个计算加减法的控件。下方是具体实现的说明:

在AddTestView中的构造方法中,我们调用了 store 对象中的 subscribe 方法,传入了一个回调方法,来对Store中存储的状态进行监听,然后获取state中最新的状态,然后赋值给组件对应的State对象。

第二段核心的代码则是dispathAction了,在输入框变化后,会根据是Add还是Desc调用下方的dispatchAction方法。如果是Add, 就会调用addTowNumber方法创建一个 加法动作对应的Action。如果是减法操作的话,则会调用 descTowNumber()方法创建一个减法对应的Action对象。然后把创建好的对象,通过store.dispatch(action) 方法派发出去。

store收到 Action后就会执行对应的 Reducer方法,然后去跟进Action提供的信息修改 Store中存储的State值。当State值被修改后,就会执行 subscriber 对应的回调方法获取最新的结果值,并赋值给组件内部的State对象进行展示。

下方AddTestView的全部代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 仅仅使用redux
import React, { Component } from 'react';
import { Action } from 'redux';
import {Text, TouchableOpacity, View, StyleSheet, TextInput} from 'react-native';
import { store } from './store';
import {addTowNumbers, descTowNumbers, CountActionType} from './action';
const {
    DESC,
    ADD
} = CountActionType;

type State = {
    addResult: number,
    descResult: number
};

const styles = StyleSheet.create({
    textInput: {
        width: 60,
        borderRadius: 4,
        borderWidth: 0.5,
        borderColor: 'gray'
    },
    tipText: {
    }
});

export default class AddTestView extends Component<null, State> {
    addFirstNumber: string = '0';
    addSecondNumber: string = '0';
    descFirstNumber: string = '0';
    descSecondNumber: string = '0';

    constructor (props: any) {
        super(props);
        this.state = {
            addResult: 0,
            descResult: 0
        };
        store.subscribe(() => {
            const {
                addResult,
                descResult
            } = store.getState();
            this.setState({ addResult, descResult });
        });
    }

    firstTextChange = (type) => (text) => {
        if (type === CountActionType.ADD) {
            this.addFirstNumber = text;
            this.dispathAddAction();
        } else {
            this.descFirstNumber = text;
            this.dispathDescAction();
        }
    }

    secondTextChange = (type) => (text) => {
        if (type === CountActionType.ADD) {
            this.addSecondNumber = text;
            this.dispathAddAction();
        } else {
            this.descSecondNumber = text;
            this.dispathDescAction();
        }
    }

    dispathAddAction = () => {
        const action = addTowNumbers({firstNumber: this.addFirstNumber, secondNumber: this.addSecondNumber});
        store.dispatch(action);
    }

    dispathDescAction = () => {
        const action = descTowNumbers({firstNumber: this.descFirstNumber, secondNumber: this.descSecondNumber});
        store.dispatch(action);
    }

    calculate = (type) => {
        const calculateText = type === CountActionType.ADD ? '+' : '-';
        const result = type === CountActionType.ADD ? this.state.addResult : this.state.descResult;
        return (
            <View style={{flexDirection: 'row'}}>
                <TextInput style={styles.textInput} defaultValue={'0'} onChangeText = {this.firstTextChange(type)}/>
                <Text> {calculateText} </Text>
                <TextInput style={styles.textInput} defaultValue={'0'} onChangeText = {this.secondTextChange(type)}/>
                <Text> = </Text>
                <Text>{result}</Text>
            </View>
        );
    }

    render () {
        return (
            <View style={{ justifyContent: 'center', alignItems: 'center' }}>
                {this.calculate(CountActionType.ADD)}
                {this.calculate(CountActionType.DESC)}
            </View>
        );
    }
}
5、总结

介绍完相关的Demo,我们可以总结一些具体的实现流程。上述各个部分的执行过程是比较简单的,下方是具体的总结:

  • Component 也就是下边的AddTestView 是不会直接调用 Reducer 方法来修改状态的,而是像 Store 通过Dispatch来派发Action的方式向Store下发修改State的命令。
  • Store在收到 Component 派发的 Action 后会调用对应的 Reducer。
  • Reducer则根据提供的Action信息来修改对应的State的值,并返回给Store,更新。
  • Component最终通过Subscribe的方式接收到更新后的State,当然派发 Action 的Component 与 Subscriber 对应状态的 Component 大部分情况下不是一个。

上面是根据上述示例来画的简图,下方我们可以脱离上述demo, 整理了一个图。从下图中不难看出,平时在开发时,Component一般是有多个的,而Store只有一个,这些Component都像Store派发Action修改对应的状态,并且可以通过Subscriber来监听对应状态值的改变。

而Reducer也可以是多个,建议将Reducer按照修改状态的类型或者相关的业务逻辑进行拆分,拆分成多个业务模块。修改不同的状态时,会调用不同的Reducer。

上述我们是声明定义了一个Reducer ,如果修改State的东西都写在一个方法里,难免会有些难于维护。所以一般会对Reducer进行拆分,下方是对上述Reducer拆分后的代码。当然运行效果与之前的是一样的,下方也是推荐用法。

虽然该Demo, 使用Redux实现会比较麻烦,使用组件内部的State完全可以实现,因为是为了窥探Redux的使用方式,所以我们就用Redux实现了该demo。但是如果是跨组件的数据交流,该方式就比较合适了。

本篇博客就先到这儿吧,虽然本篇博客介绍了Redux, 但是在开发中很少直接使用,一般会结合着其他框架及中间件使用。之前还积累了一些 react-redux, 以及redux-thunkredux-saga 的东西,下篇博客把react-redux相关的东西在总结一下,做个记录也便于自己后期翻阅。最后附上redux的文档链接,有啥问题可翻阅https://www.redux.org.cn/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深度理解Redux原理并实现一个redux
Redux的作用在于实现状态传递、状态管理。在这里你可能会说了,如果是状态传递,那我props的传递不也是可以达到这样的效果吗?context上下文方案不也是可以达到这样的效果吗?没错,是这样的,但是上述的两种方案是有局限性的。
夏天的味道123
2022/10/19
4360
redux基础概念及执行流程详解
全局有一个公共的容器(所有组件都可以操作),我们可以在某个组件中把全局容器中的信息进行修改,而只要全局信息修改,就可以通知所有用到该信息的组件重新渲染(类似于发布订阅)==》redux就是这种解决方案:redux只有一个作用,就是为了实现组件之间的信息交互。
柴小智
2020/02/14
8410
React和Redux——状态管理Flux和Redux
在强调组件化的React中,我们需要以高内聚、低耦合的原则设计高可复用性的组件。因此渲染组件的数据由两部分组成,一个是由父组件传入的Props参数、一个是组件的内部状态State。Props参数可以是任何的Javascript对象,作为组件本身可以通过使用propTypes限制必须输入的参数和输入参数的类型以保证组件的可用性。State负责维护组件内部的状态,组件内部必要时可以通过触发父组件传递的回调函数传递信息给父组件或者将State以Props的形式传递给子组件。
lyndonxdlin
2018/07/05
1.9K0
React 进阶 - React Redux
应用初始化时候,只请求一次数据,然后通过状态管理把数据存起来,需要数据的组件只需要从状态管理中‘拿’就可以了。
Cellinlab
2023/05/17
1K0
React 进阶 - React Redux
React/ReactNative 状态管理: redux 如何使用
有同学反馈开发 ReactNative 应用时状态管理不是很明白,接下来几篇文章我们来对比下 React 及 ReactNative 状态管理常用的几种框架的使用和优缺点。
张拭心 shixinzhang
2023/03/27
1.4K0
实现redux
上面实现了兄弟组件的通信,但是复用性差,而且store里的listeners不应该被外界修改。
一粒小麦
2019/07/18
7810
实现redux
Redux(一):基本概念
React是一个单向数据流的view层框架,单向数据流、组件化、生命周期是其特点。在React组件关系中,组件状态由自己管理,父子组件通过props传递;兄弟组件那么就需要一个共同的父组件作中转;如果涉及层级比较深的话一层一层传递会非常麻烦。所以大量状态共享是React单独难以解决的问题。
Ashen
2020/06/01
1.3K0
React、Flux以及Redux小结
React和Vue是当下前端最流行的Javascript框架。作为一名现代化前端工程师,学习这两个框架已经成为了标配。 本人学习这两个框架已经有很长一段时间了,当下对其做一些基本概念梳理总结,利人利己。
epoos
2022/06/06
6910
React、Flux以及Redux小结
Redux初学者入门解析
Redux是一个流行的JavaScript框架,为应用程序提供一个可预测的状态容器。Redux基于简化版本的Flux框架,Flux是Facebook开发的一个框架。在标准的MVC框架中,数据可以在UI组件和存储之间双向流动,而Redux严格限制了数据只能在一个方向上流动。其工作流程如下图
henu_Newxc03
2021/12/28
6310
Redux初学者入门解析
redux架构基础
本文书接 从flux到redux , 是《深入浅出react和redux》为主的比较阅读笔记。
一粒小麦
2020/01/02
1.3K0
深入浅出redux知识
为了防止自己手动调用 store.dispatch ,一般会使用redux的这个 bindActionCreators 方法来自动绑定 dispatch 方法,用法如下。
Qiang
2019/06/12
1K0
深入浅出redux知识
深入学习 Redux 之基础用法
① Web 应用是一个状态机,视图与状态是一一对应的。 ② 所有的状态,保存在一个对象里面。
Leophen
2021/07/16
4810
深入学习 Redux 之基础用法
Redux/react-redux/redux中间件设计实现剖析
在一切开始之前,我们首先要回答一个问题:为什么我们需要redux,redux为我们解决了什么问题?只有回答了这个问题,我们才能把握redux的设计思路。
Nealyang
2020/04/23
2.3K0
Redux/react-redux/redux中间件设计实现剖析
从应用到源码-深入浅出Redux
文章中的每一行代码都是笔者深思熟虑敲下的,欢迎对 Redux 感兴趣的同学共同讨论。
19组清风
2022/08/30
1.4K0
从应用到源码-深入浅出Redux
自己简写一个redux(redux源码简写)
 直接看代码 mydux.js文件 function createStore(reducer) { /** * 1.注册用到的方法,并return出去提供使用 * 2.定义默认的状态与事件池 * 3.默认先触发一次dispatch给state赋予默认值 * 4.componentDidMount后会通过subscribe往状态池中追加事件 * 5.在具体的事件处触发dispatch,传入具体的action,修改state的值,并且触发事件池中的事件,
柴小智
2020/02/14
7140
从0实现一个mini redux
本文从 redux 原理出发,一步步实现一个自己的 mini-redux,主要目的是了解其内部之间的各种关系,所以本篇不会讲解太多关于 redux 的用法
落落落洛克
2021/01/18
6750
深入Redux架构
关于redux 之前写了一篇通过一个demo了解Redux,但对于redux的核心方法没有进行深入剖析,在此重新总结学习,完整的代码看这里。(参考了React 技术栈系列教程) 什么情况需要用redu
牧云云
2018/05/02
2.3K0
深入Redux架构
Redux原理分析以及使用详解(TS && JS)
简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
前端小tips
2021/11/25
4.8K0
Redux原理分析以及使用详解(TS && JS)
React进阶(3)-上手实践Redux-如何改变store中的数据
在前面的一文React进阶(2)-上手实践Redux-如何获取store的数据当中,已经知道组件怎么获取store的数据,并渲染到页面上,那么在该节当中揭示怎么更改store的数据,实现页面的更新
itclanCoder
2020/10/23
2.7K0
Flux --> Redux --> Redux React 基础实例教程
Flux思想、Redux基本概念、Redux的使用、Redux在React中的使用(同步)、Redux在React中的使用(异步,使用中间件)
书童小二
2018/09/03
4K0
Flux --> Redux --> Redux React 基础实例教程
相关推荐
深度理解Redux原理并实现一个redux
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验