Java深度学习,目前对redux,redux-saga最通俗的解释


最近在学习react全家桶,于是做了一个基于react-pdf的在线pdf阅读项目,项目地址:

yjf27281181/react-readme​github.com

里面一些异步操作(登录,查询数据库等)参考了另外一个博客项目的异步操作,由于之前没有接触过react,猛然看到如此纷繁复杂的处理流程实属懵逼,在知乎也看了不少大牛的文章,但还是觉得通俗性差了一丁点火候,正好趁机会记录一下我对redux和redux-saga的理解。

一、为什么要用redux

每一个工具的出现都是为了解决某一个痛点,react的痛点就是繁琐的props和state操作,举个例子:A主页下有个工具栏B,工具栏B下有个按钮,按钮可以更新控件D,但只能通过A->C->D,这个时候如果想要点击B下的按钮更新D,需要将数据作为props从A传到C传到D,然后再在A中写一个函数用来更新这个state,然后把这个函数作为props传入B,作为按钮的点击事件。

由于操作实在过于复杂,你想到能不能直接在B中修改D的state呢?于是redux就诞生了,当然,redux并不是让你能从B组件直接更改D的state,而是通过更改公共state,改完之后再通知D去更新state。下面举个例子说明这个过程。

二、通俗易懂的例子

那么什么是公共state,如何修改公共state呢?到这里,你在别的地方应该已经看到了什么action,纯函数,reducer之类的东西了,如果你还是不懂,请看下面这个例子。

假设你(组件B)的银行账户上有500元(公共state),你想将其中的100元转到别的地方(比如支付宝),且你和你的女朋友(组件D)同时订阅了这个账户的短信提醒。这时,你是不可能直接去银行然后操作银行电脑进行转钱的(不能直接修改公共state),假设你由于感冒了不能说话,于是你只能走到柜台前,递给操作员(reducer)一个条子(action),写着:

操作类型:转账

金额: 100

目的地:支付宝

你把这个字条递给操作员,然后操作员开始更新你的余额,更新完成之后短信提醒你和你的女朋友state已经更新了,然后你的女朋友就知道你的余额从500变成400了。

三、例子代码化

那么如何用代码实现这个流程呢?

首先我们来看银行的工作,银行就是reducer,它能支持各种各样的操作(action),现在我们把这个操作写出来。

bankReducer.js

export const actionTypes = {

转账: "转账",

存钱: "存钱",

取钱:"取钱"

}

const initialState = {

余额: 500

};

现在我们有了三个操作,分别是转账,存钱和取钱,然后我们需要定义一个reducer函数,来告诉操作员当遇到这些actionType的时候分别做什么处理

export function reducer(state = 初始值, 操作) {

switch (操作.type) {

case actionTypes.存钱:

return {

余额: state.余额+action.存入金额

};

case actionTypes.取钱:

return {

余额: state.余额-action.取出金额

},

case actionTypes.转账:

return {

余额: state.余额-action.转账金额

};

}

现在,当操作员拿到用户递过来的纸条的时候就能进行相应的操作了,但是用户能进行什么样的操作呢?于是银行还应该提供一些接口,告诉用户可以进行哪些操作:

export const actions = {

存钱_操作: function(存入金额) {

return {

type: actionTypes.存钱,

存入金额

};

},

取钱_操作: function(取出金额) {

return {

type: actionTypes.取钱,

取出金额

};

},

转账_操作: function(转账金额) {

return {

type: actionTypes.转账,

转账金额

};

},

}

让我们再重新梳理一下整个流程,用户首先填写信息到action,你可以理解为用户写了一个小纸条,比如转账,那么用户可以这样调用:

转账_操作(100)

那么function生成的小纸条就是

{

type: actionType.转账,

100

}

然后这个小纸条就会自动递给操作员(reducer,是的,你不用管是怎么给reducer的),然后操作员看到这个action的type是转账,那么进入转账操作:

case actionTypes.转账:

return {

...state,

余额: state.余额-action.转账金额

};

这时,你的余额就更新为400了。

好了,现在整个银行都完成了,我们来看用户的部分,也就是你

you.jsx

首先我们需要一个按钮,按一下就转账100,怎么实现呢?

class You extends Component {

constructor(props) {

super(props);

this.state = {

余额: 0

};

}

onClick = (e)=>{

//点击之后进行转账

}

render() {

return

}

}

有人可能会问,为什么这里余额是0?因为余额需要银行统一通知,而不是自己设置的,那么现在就与要把你和银行连接起来,使得你能将小纸条递给操作员,也能收到银行的消息:

于是你就能看到之前头疼的两个函数了:mapStateToProps和mapDispatchToProps,那这两个函数作用是什么呢?

mapStateToProps:将银行的state更新到本地

mapDispatchToProps: 让你能使用银行提供的操作接口

先说mapStateToProps,我们现在state中只有“余额”这一个属性,但是实际上公共state中可能有很多其他的属性,比如

const initialState = {

余额: 500,

行长姓名: 颜小四,

银行地址: 佐家垄职业技术学院旁的螺狮粉店里,

...

};

这些信息可能其他组件关系,但是你并不关心,所以当你更新本地state的时候,只需要更新余额就行了

function mapStateToProps(state) {

return {

余额: state.余额,

};

}

这个函数的意思是,当我账户中余额属性更新时,同步到我的组件属性里(想要更新UI,需要调用componentWillReceiveProps,并在里面调用setState)

同样,银行可能提供很多操作,但是我只关心“转账”操作,于是可以只将转账操作映射过来,然后“我要转账”会作为函数,存在this.props里,调用方式为this.props.我要转账(注意这个函数的参数是与银行中的action参数一致的,转账操作的参数为“转账金额”):

import { actions as bankActions } from "bank.js";

function mapDispatchToProps(dispatch) {

return {

我要转账: bindActionCreators(bankActions.转账_操作, dispatch),

};

现在,准备工作完了,将你和银行连接即可

export default connect(

mapStateToProps,

mapDispatchToProps

)(You)

这样你就成功地与银行连接了,你能调用银行的给出的接口了。现在,如果我们就能写onClick函数了,点击之后写入小纸条(action),纸条会自动交给操作员(reducer)更改你的余额(state)。

onClick = (e)=> {

this.props.我要转账(100) //填写转账小纸条,写入转出金额为100

}

现在你已经能操作银行了,那怎么让女朋友也接受到通知呢?首先我们定义女友这个组件:

notExist.jsx

class notExist extends Component {

constructor(props) {

super(props);

this.state = {

余额: 0

};

}

render() {

return

{this.state.余额}

}

function mapStateToProps(state) {

return {

余额: state.余额,

};

}

export default connect(

mapStateToProps,

)(notExist)

}

可以看到,我们只需要写好mapStateToProps, 并且connect到银行,那么你的女友就能收到通知了

结束语

感觉写了很多了,如果反响好的话我会更新我对redux-saga的理解。

本文出自知乎

Java深度学习,目前对redux,redux-saga最通俗的解释

更多相关内容,Java架构师,软件开发等学习资料,电子书及视频还有高级讲师公开课免费资源

需要的可以私聊小编发送【学习】二字


分享到:


相關文章: