对不起本文确实有标题党的嫌疑:) 想要理解本文还是要先会用react和es6,如果连react和es6都不知道是什么的话我也没辙:(

如果你选择用react来开发应用,并且你没对各个组件的状态进行应有的管理,那么当应用变得庞大的时候你会发现组件之间的通信变得错综复杂,各个组件之间的数据传递往往会乱成一团,从而导致加班、延期、炒鱿鱼等不好的事情:( 这个时候就需要引入“状态管理”这个概念来挽救一团乱麻的代码。状态管理,就是将各个组件之间相互独立的状态和数据给统一的管控起来,让原本错综复杂的数据流向变成单向,这样状态就变得容易管理和理解,从而让程序变得易于维护。

今天我们讲的就是react目前最流行的状态管理工具redux和它的一些周边组件。废话不多说,我们先准备好react开发环境,打开ide开始敲代码。

环境这块我就不讲了,最基础的webpack+react即可。

首先先安装redux(yarn add redux -S),清空src目录,新建一个入口js文件(index.js),输入以下内容:

import { createStore } from 'redux'

const reducer = function (state, action) {
console.log(action.type)
return state
} const store = createStore(reducer) store.dispatch({type: 'hello'})

然后启动dev server,打开浏览器和控制台,就可以看到输出了“hello”。现在来稍微解释下这段代码:

createStore,从字面上理解,就是创建仓储,这个仓储用来存放数据和修改数据的方法。

dispatch,直译过来是指派、调度,可以理解成命令store执行修改数据的操作。传入一个对象来描述要执行的动作。我们称这个对象为action。

reducer,直译过来是还原剂,这里就把它理解成存放数据和修改数据的方法的地方。如果把store比喻成仓库,那么reducer就是用来装载货物的集装箱。reducer接受的第一个参数是数据,第二个参数用来描述动作,里面是dispatch过来的对象和数据,我们可以利用type属性结合switch case语句来进行具体的状态修改。还有要记得返回state,如果没有返回state就会报错。

我们把reducer扔到createStore这个函数里,就返回了一个store。然后再调一下store里面的dispatch方法,就执行了一次reducer。这样一个最简单的redux管理状态的流程就跑完了。

在这个例子里我们只使用了一个reducer,而一个reducer只有一个state,但是我们的应用肯定不止一个组件,这个时候就需要多个reducer。

为了将多个reducer组合起来,我们又要引入一个redux里的函数,叫combineReducers。

import {combineReducers, createStore} from 'redux'

const list = function (state = [], action) {  //state=[]表示的是state的初始状态
console.log(action.type)
console.log('list')
return state
} const counter = function (state = 0, action) {
console.log(action.type)
console.log('counter')
return state
} const reducers = combineReducers({
list, counter
}) const store = createStore(reducers) store.dispatch({type: 'hello'})

这样就将多个reducer组合起来了。调用dispatch的时候所有reducer都会被执行。

到了这里我们就已经可以进行一些简单的本地状态管理了。但是几乎所有的应用都有涉及到ajax异步请求,这些代码要放到哪里呢?如果放到reducer里的话由于reducer要求立即返回state,不然报错。解决方案是有的,不过有些繁琐,可以参考阮一峰老师的教程:

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html

如果没看懂的话也没关系,如果你能够在项目中运用redux-saga的话,就可以很轻松的解决异步问题了:)

我们先认真的把redux-saga官方提供的案例给看一看

https://redux-saga-in-chinese.js.org/docs/introduction/BeginnerTutorial.html

redux-saga的使用很简单,和之前redux的做法差不多。先定义saga(也称为effect。类似reducer,不过可以调用异步方法,不能修改状态),然后在顶层(index.js)注册之前写好的saga即可。

在saga(effect)中,我们可以通过takeEvery来监听dispatch,通过call来调用异步方法,通过put来触发reducer,通过select来获取状态。要注意的是saga都是Generator函数(带*号),也只有Generator函数里才能调用yield。这样异步问题就差不多解决了。

说了这么多,总得应用到react里面去吧。react里的各个组件想要获取到store里的状态和命令store进行数据修改,如果不安装其他包的话就只能在根级组件把store一级一级的传递下去,中间有一级没传递store那么之后的组件就全部无法使用redux进行状态管理了,这样显然是有待改进的。所以我们还要再装一个包:react-redux。

React-redux核心的方法只有两个:Provider和connect。Provider用来包裹根级组件,并接收store,connect用来将组件的props与store连接起来,这样即使不一层层的传递store每个组件也可以接收到store。

export default connect((state) => {
return {list: state.userList.list} // 将store与组件连接起来。connect第一个参数是一个函数,要求返回用来描述props和store的对象。
})(List)

这样我们基本上就能把redux给实际的应用起来了,但是还有一个问题值得我们思考:store调用dispatch后所有的reducer都会被执行,而每个reducer里面只能用switch case之类的流程控制语句来指定执行哪个reducer,如果项目一大,各个方法的命名岂不是很容易混乱?别着急,这个时候需要本文要谈到的最后一个包:dvajs。dvajs将一组数据和相应的修改数据的方法包装成一个module,组件调用dispatch的时候可以通过指定type属性来直接调用相应module的effect或者reducer。dvajs的具体使用除了参考官网的案例以外,还可以参照这篇博文:https://www.cnblogs.com/axel10/p/8503782.html。只要你能够从redux->redux-saga->react-redux这个流程学下来,就会发现dvajs几乎没有多少新知识点,很快就能够上手。

如果觉得教程里有地方讲的不是很理解的可以将下面这个案例下载下来看一看,相信很多问题都会得到答案。

一个在线获取用户列表,点击项目可删除的例子

https://github.com/axel10/react-redux-redux-saga-example

谁都能听懂的Redux+Redux-Saga超级傻瓜教程的更多相关文章

  1. 条件期望:Conditional Expectation 举例详解之入门之入门之草履虫都说听懂了

    我知道有很多人理解不了 "条件期望" (Conditional Expectation) 这个东西,有的时候没看清把随机变量看成事件,把 \(\sigma\)-algebra 看成 ...

  2. Flux --> Redux --> Redux React 入门

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  3. [Redux] redux的概述

    redux 的概述 随着 javascript 单页应用的不断发展,javascript 需要管理比以往都要多的状态,管理不断变化的 state 非常困难,数据流动不断变的模糊不可预测,代码的开发与维 ...

  4. [React] 11 - Redux: redux

    Ref: Redux中文文档 Ref: React 讀書會 - B團 - Level 19 Redux 深入淺出 Ref: React+Redux 分享會 Ruan Yifeng, Redux 架构: ...

  5. Flux --> Redux --> Redux React 基础实例教程

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  6. Flux --> Redux --> Redux React 入门 基础实例使用

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  7. 基于 Redux + Redux Persist 进行状态管理的 Flutter 应用示例

    好久没在 SegmentFault 写东西,唉,也不知道 是忙还是懒,以后有时间 再慢慢写起来吧,最近开始学点新东西,有的写了,个人博客跟这里同步. 一直都在自己的 React Native 应用中使 ...

  8. 每个程序员都可以「懂」一点 Linux

    提到 Linux,作为程序员来说一定都不陌生.但如果说到「懂」Linux,可能就没有那么多人有把握了.到底用 Linux 离懂 Linux 有多远?如果决定学习 Linux,应该怎么开始?要学到什么程 ...

  9. 每个java初学者都应该搞懂的问题

    对于这个系列里的问题,每个学JAVA的人都应该搞懂.当然,如果只是学JAVA玩玩就无所谓了.如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列.内容均来自于CSDN的经典老贴. ...

随机推荐

  1. Codeforces Round #464 (Div. 2) D. Love Rescue

    D. Love Rescue time limit per test2 seconds memory limit per test256 megabytes Problem Description V ...

  2. poj 2139 奶牛拍电影问题 floyd算法

    题意:奶牛拍一系列电影,n头牛拍m部电影,同一部电影种的搭档们距离为1,求最小距离? 思路:Floyd 图 最短路径 存图: 初始化图 for (int i = 0; i <= n; i++) ...

  3. 利用本地SQL Server维护计划来维护SQL Database

    On-Premise的SQL Server提供了维护计划来定期.定时的维护SQL Server.一般的做法是:定义SQL Server Agent Jobs,而后维护计划帮助我们定期.定时执行SQL ...

  4. JDK各版本新特性浅谈

    JDK 5.0 自动拆装箱 枚举 可变参数 泛型 For -each 内省 静态导入 JDK 6.0 console开发控制台程序 轻量级HTTP ServerAPI 支持脚本语言 使用Compile ...

  5. JSP自定义tld方法标签

    卧槽 我们可以通过tld文件,自定义一个方法标签,以便在页面中使用,目录通常放在WEB-INF下面的tlds文件夹: 引入方式示例,直接在jsp上引入tld标签文件: <%@ taglib pr ...

  6. 记一次Entity Framework 项目的优化过程

    在博客园看了不少其他大神的经验.今天也抽空贡献点自己的经验(并不是说自己也是大神..小弟还只新手程序员去年才毕业的) 好了废话不多说,直接进入主题.(具体的好坏各位看官就随便看看吧..没有什么好坏之分 ...

  7. 47.关于gradle的解疑

    Short Answer Gradle is a build system. Long Answer Before Android Studio you were using Eclipse for ...

  8. Windows网络编程笔记2

    这一次看看重定向器和如何使用Netbios函数获取本机mac地址 5.获取Mac地址 利用NCBASTAT命令实现,适配器状态命令会返回一个 ADAPTER_STATUS结构,紧接着是大量 NAME_ ...

  9. MFC DLL 可以封装MFC的窗体 供别的MFC程序使用

    MFC DLL  可以封装MFC的窗体 供别的MFC程序使用 在庞大程序分工里面 非常可取. 可以细分每个窗体就是单独的 模块. [后续不断完善]

  10. Robotium测试报告的生成方法(下)

    7.4 测试报告优化 通过上面的三种方法,我们都可以得到一个Xml格式的测试报告,不过这不是我们想要的,因为这样的报告读起来很费劲,而且这样的报告发给领导们也是不行的.所以我们要美化一下才行,一般都是 ...