对不起本文确实有标题党的嫌疑:) 想要理解本文还是要先会用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. HihoCoder - 1636 Pangu and Stones(区间DP)

    有n堆石子,每次你可以把相邻的最少L堆,最多R堆合并成一堆. 问把所有石子合并成一堆石子的最少花费是多少. 如果不能合并,输出0. 石子合并的变种问题. 用dp[l][r][k]表示将 l 到 r 之 ...

  2. Codeforces Round #496 (Div. 3) ABCDE1

    //B. Delete from the Left #include <iostream> #include <cstdio> #include <cstring> ...

  3. 洛谷 P1736 创意吃鱼法(多维DP)

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  4. Linux命令之---mkdir

    命令简介 mkdir 命令用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目录名不能是当前目录中已有的目录. 命令格式 mkdir [选项] 目录...(这里可以是多个目 ...

  5. datagrid的基本属性&查询和清空功能的实现

    1.datagrid基本属性 <script charset=UTF-8"> $(function(){ $("#datagrid").datagrid({ ...

  6. PostgreSql基础命令及问题总结

    本章内容: 1.基本命令 基本命令 1.psql -U cdnetworks_beian -d cdnetworks_beian         #-U指定用户,-d指定数据库 2.\l        ...

  7. Hyper-V 网络虚拟化技术细节

    Hyper-V 网络虚拟化技术细节 适用对象:Windows Server 2012 R2 服务器虚拟化能让多个服务器实例在同一台物理主机上同步运行,但各个服务器实例都是相互独立的. 每台虚拟机的运作 ...

  8. STL学习笔记7 ---- algorithm(算法)

    STL中算可以分为三种, 1.变序型队列算法,可以改变容器内的数据: 2.非变序型队列算法,处理容器内的数据而不改变他们 : 3.通用数值算法,这涉及到很多专业领域的算术操作,这里不做介绍. 第一是变 ...

  9. uncompyle2反编译python的.py文件

    前几天学用github,一不小心把a.py文件给删除了,由于1天没有提交,也无法找回.突然发现同a.py文件生成的编译文件a.pyc还在,逐去搜索一番反编译的方法. 查询得知python比较好的工具u ...

  10. 【转】MapReduce:默认Counter的含义

    MapReduce Counter为提供我们一个窗口:观察MapReduce job运行期的各种细节数据.今年三月份期间,我曾经专注于MapReduce性能调优工作,是否优化的绝大多评估都是基于这些C ...