对不起本文确实有标题党的嫌疑:) 想要理解本文还是要先会用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. C++实例 MySTLString

    #include <iostream> #include <cstring> #include <string> using namespace std; clas ...

  2. HUD:2896-病毒侵袭

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memor ...

  3. 笔记-python-standard library-12.1 pickle

    笔记-python-standard library-12.1 pickle 1.      pickle简介 source code: Lib/pickle.py pickle模块实质上是一个实现p ...

  4. Java模拟音乐播放器 暂停与重新播放——线程如何控制另外一个线程的状态

    package com.example.Thread; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEve ...

  5. TCP/IP网络编程之套接字与标准I/O

    标准I/O函数 标准标准I/O函数有两个优点: 标准I/O函数具有良好的移植性 标准I/O函数可以利用缓冲提高性能 关于移植性无需过多解释,不仅是I/O函数,所有标准函数都具有良好的移植性.因为,为了 ...

  6. MySQL时间字段究竟使用INT还是DateTime

    今天解析DEDECMS时发现deder的MYSQL时间字段,都是用 `senddata` ) unsigned '; 随后又在网上找到这篇文章,看来如果时间字段有参与运算,用int更好,一来检索时不用 ...

  7. iOS下单例模式实现(二)利用宏定义快速实现

    在上一节里提到了用利用gcd快速实现单例模式. 一个项目里面可能有好几个类都需要实现单例模式.为了更高效的编码,可以利用c语言中宏定义来实现. 新建一个Singleton.h的头文件. // @int ...

  8. sql server备份

    完全备份 declare @device varchar(255),@path varchar(255),@dbname varchar(255)set @dbname='MIS_TEMP'set @ ...

  9. Anaconda的用法

    1. conda list -----显示anacoda安装的模块 2.jupyter notebook----启动网页上的python编程环境 3.anacoda  search -t conda ...

  10. webpack vue-cli 常见问题总结

    1. webpack打包压缩 ES6 js..vue报错: ERROR in js/test.js from UglifyJs Unexpected token punc ?(?, expected ...