这是Webpack+React系列配置过程记录的第六篇。其他内容请参考:

这篇文章的主要内容包括: 1. 修改一下之前存在的问题; 
2. 在框架中引入redux,使用一个例子简单介绍redux的使用方法; 
3. 其他redux辅助库。

修复遗留问题

  1. webpack.prod.config.js中缺少了对path库的引用,执行构建npm run build:prod的时候失败。在文件开始的地方引入node.js的path库就可以了。
  2. package.json里面定义了一个build:dev的脚本,这个脚本其实有点多余,不过有时候需要打包测试版本的文件,所以还是需要存在。主要有个问题是webpack.dev.config.js中output节点下错误定义了path的值为根目录'/',这在使用npm start命令启动运行时打包的时候看不出问题,但是在使用npm run build:dev时会出现无法写文件到根目录的权限错误。只要把path的值改掉就可以。path: config.publicPath改成path: config.staticPath,publicPath: config.publicPath
  3. css-loader和less-loader导出的样式类名太长,还是把localIdentName中的path部分去掉比较好看。

redux

安装redux

安装依赖的命令如下:

  1. npm install --save redux react-redux redux-thunk
  2. npm install --save-dev redux-logger

redux不用说了,我是把它当成一个本地数据库使用,react-redux帮助你完成数据订阅,redux-thunk可以放你实现异步action,redux-logger是redux的日志中间件。

关于redux与代码布局

在开始介绍之前我想先就redux的使用发表一些自己的看法:

前文说了我把redux当成一个本地数据库,因此我倾向于把redux封装类似于mvc中的Model的角色,独立为一层。这与另一种观点——我在公司的项目更倾向于把每个页面当成一个独立模块,每个模块维护自己的reducer和action的观点,有所出入。

我的做法可以更好地实现reducer的复用。而对我自己来说更重要的好处是集中修改。更适合小项目或者独自开发一个项目的场景。

我公司的项目的做法对多人协同开发更有利,毕竟每个人维护好自己的代码就可以了。公司项目的这种方法有几个问题让我比较难以接受:

第一个是模块越多reducer和action的定义越多,很多时候这些代码都是差不多的。

更重要的是第二个问题:模块数据在store里面的存储是直接在根state下面排列下来的,根state的数据格式样式有点像这样:

  1. {
  2. aModuleData:{...},
  3. bModuleData:{...},
  4. cModuleData:{...},
  5. dModuleData:{...},
  6. ...
  7. }

项目的原意是希望每个模块的保持独立,但实际上使用的时候却是有极大的可能出现aModule同时使用aModuleData和bModuleData的情况。这跟每个人维护自己的代码的初衷有悖,也没有发挥好redux的真正能力。

还有一个小问题是reducer的组织通常影响着应用数据state的样式,把reducer分散到每个模块之后,state的形式在代码上很难直管地反映出来,特别是当模块是动态加载的时候更甚。不过借助logger等工具可以解决。

关于这块的争议Redux的教程中有提及。

使用redux

无论代码怎么布局,使用redux的方法主要还是三步曲:创建store、创建action、创建reducer。而在这之后才是与业务或者组件相关的数据处理和展示。

先看一下我的做法的代码布局:

创建store的代码集中在model/index.js中,model/actions/.js和model/reducer/.js里面分别是写action创建函数和reducer函数的地方,根据模块可以自己DIY。

model/index.js的代码如下:

model/actions/index.js的代码如下:

这里定义了一个名叫login的异步actionCreator以及三个普通的actionCreator。

actionCreator被某个组件调用后会向store发送action,然后被reducer处理,reducer定义在model/reducers/index.js中,代码如下:

这就完成了三步曲了。上面的代码简单地模拟了登录的动作。登录页面用到的数据存放在loginPageData中,登陆后获取到的当前登录用户数据存储在实体数据entities中。

接下来要把redux和react联系起来,也就是把redux的store中的数据交给react的组件使用。

第一步需要挂载redux的store到react,为react提供数据支持。最简单的做法是找到应用的根组件(我这里是BasicExample.js),然后在它的render函数中最外层添加Providor标签。代码片段如下:

红线部分画出了改动点,从model/index.js中导出了store对象,通过react-redux提供的Providor标签挂载到react中,为react提供数据支持。

看最后的红线中,我们在Home组件里面添加了这次的测试例子ReduxDemo。它的代码如下:

代码的重点在connect函数。这个函数也是由react-redux提供的。使用它可以包装普通的展示组件(这里是ReduxDemo——只负责展示数据),然后返回一个容器组件。connect函数通过第一个参数让展示组件订阅了来自store的数据;通过第二个参数让展示组件默认可以dispatch各种action。

这个例子在ReduxDemo挂载完成后调用login接口模拟登陆。返回结果被塞到store中(数据格式由先前写好的reducers的组织方式决定)。页面根据store中的数据展示内容。由于login发出的远程请求是假的,所以这里总是失败,因此会显示失败的内容。

关于redux的使用介绍到此结束。

redux辅助库

其实在上面的代码中我已经悄悄地提及了两个辅助库,也是我想在这里推荐的两个库:

  1. 开发工具redux-devtools:结合各种其他库可以实现可视化的调试界面。
  2. 数据规范化工具normalizr:规范化组织数据。经过三个项目的体验后,个人非常推荐使用这个库,可以让应用的数据组织更清晰、减少冗余数据、减少因数据刷新导致的性能影响。

暂时不在这里展开介绍,有兴趣的可以到github上查一下文档。

源码下载地址:https://pan.baidu.com/s/1dENYfuh

在React中使用Redux的更多相关文章

  1. react系列(五)在React中使用Redux

    上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...

  2. 在react中使用redux并实现计数器案例

    React + Redux 在recat中不使用redux 时遇到的问题 在react中组件通信的数据是单向的,顶层组件可以通过props属性向下层组件传递数据,而下层组件不能向上层组件传递数据,要实 ...

  3. react中使用redux简易案例讲解

    为什么我想要使用redux? 前段时间初步上手了react,最近在使用react的过程中发现对于组件之间通信的需求比较迫切,尤其是在axios异步请求后端数据的时候,这样的需求是特别强烈的!举个例子: ...

  4. react中对于redux的封装

    const createStore = (reducer)=>{ //默认的state对象 let state = {}; //将所有订阅的事件存在在这个数组中 let listeners = ...

  5. 在React中使用Redux数据流

    问题:数据流是什么呢?为什么要用数据流? 答案:1.数据流是我们的行为与相应的抽象 2.使用数据流帮助我们明确了行为的对应的响应 问题: React与数据流的关系 1.React是纯 V 层的前端框架 ...

  6. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  7. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  8. 优雅的在React项目中使用Redux

    概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在 ...

  9. react中界面跳转 A界面跳B界面,返回A界面,A界面状态保持不变 redux的state方法

    在上一篇文章中说过了react中界面A跳到B,返回A,A界面状态保持不变,上篇中使用的是传统的localStorage方法,现在来使用第二种redux的state方法来实现这个功能 现在我刚接触red ...

随机推荐

  1. MFC基础程序设计VS2015 最新03

    视频教程地址观看:http://pan.baidu.com/s/1mhKQ6kK 一.数字(浮点数或整数)转为文字:a)如果转为窄字符字符串,sprintf函数很好用,浮点数都没问题:b)如果转为宽字 ...

  2. Git总结笔记3-把本地仓库推送到github

    说明:此笔记在centos 7 上完成 1.配置公钥 [root@kangvcar ~]# ssh-keygen -t rsa -C "kangvcar@126.com" [roo ...

  3. 通过分析 JDK 源代码研究 TreeMap 红黑树算法实

    TreeMap和TreeSet是Java Collection Framework的两个重要成员,其中TreeMap是Map接口的常用实现类,而TreeSet是Set接口的常用实现类.虽然HashMa ...

  4. Java中线程的实现:

    Java中线程的实现: 一.线程简介: 实现的两种方式为: 1.Thread类 2.Runnable接口 都在java.lang中 都有共通的方法:public void run() 二.线程常用方法 ...

  5. 基于TypeScript的FineUIMvc组件式开发(开头篇)

    了解FineUIMvc的都知道,FineUIMvc中采用了大量的IFrame框架,对于IFrame的优缺点网上也有很多的讨论,这里我要说它的一个优点“有助于隔离代码逻辑”,这也是FineUIMvc官网 ...

  6. ZigZag Conversion2015年6月23日

    题目: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows l ...

  7. 如何选择版本控制系统之二---Git的研发应用场

    之前写了一篇<如何选择版本控制系统 ---为什么选择Git版本控制系统>,地址是:http://www.cnblogs.com/goldenfish/p/6876864.html,有兴趣的 ...

  8. javaWeb学习总结(2)- http协议

    一.http简介 1.基本介绍: (1)客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义客户端与web服务器通迅的格式. (2)WEB浏览器 ...

  9. spring service层单元测试

    service层测试较简单,目前大多数测试主要是针对public方法进行的.依据测试方法划分,可以分为两种:基于mock的隔离测试和基于dbunit的普通测试. mock隔离测试 配置pom.xml ...

  10. Spring Controller单元测试

    SpringMVC controller测试较简单,从功能角度划分,可分为两种.一种是调用请求路径测试,另一种是直接调用Controller方法测试. 调用请求路径测试 通过请求路径调用,请求需要经过 ...