深入理解React、ReduReact+Redux非常精炼,良好运用将发挥出极强劲的生产力。但最大的挑战来自于函数式编程(FP)范式。在工程化过程中,架构(顶层)设计将是一个巨大的挑战。要不然做出来的东西可能是一团乱麻。说到底,传统框架与react+redux就是OO与FP编程范式的对决。

简单学习某项技术并不能让建立起一个全局理解,也很难工程化。所以,我们必须要看以下几方面:

  1. 了解其独特的东西。如React中组件是pure render函数。
  2. 置新技术于上下文中。将React放在flux、redux中。才能真正看到数据单向流动。
  3. 对比看到优势。比其它的解决方案(vue, angluar,adobe flex),看其优势。
  4. 挑战。软件领域里没有银弹,有好处一定有挑战。

1. 谈谈对React的理解

1.1 独特性

  • Virtual Dom:又一个虚拟层、中间层、cache层,大胆的跳出了web的DOM实现约束,实现更加理想的UI编程模型:树型控件组织、统一事件、统一数据传输通道(props)。可以把Dom render到web,navtive的GUI系统上,这非常美妙,Learn once, Use Everywhere。
  • 轻Component:React的component强调pure render,把业务逻辑放到其它子系统中,如redux中的reducer。
  • 组件状态(state)要最小化的,按官方说法,不是props传入的,随时间变化的,不能是通过其它的props和stat计算而来。
  • 常用的设计模式:创建多个只负责渲染数据的无状态(stateless)组件,在它们的上,是有状态(stateful)组件。有状态组件封装了所有用户的交互逻辑,而这些无状态组件则负责声明式地渲染数据。
  • 设计范式是数据驱动组件来render。对比OO范式,OO有时会把compoent搞成自闭的、复杂的类,里面藏了太多的状态,调测很难跟踪。

1.2 置React于上下文中

React的virtual DOM想要构建一个理想的前端模型,那理想的前端编程到底是如何呢?我个人总结的4点:

  1. 构建基本UI能力:不论是组件拖拉(VB),还是写树型XML描述文档,能快速做出和直觉一致的UI界面
  2. 数据绑定:与数据层(model)绑定数据,展示一个有数据的UI
  3. 用户交互:用户点击、触摸,程序完成业务逻辑,并反馈给用户,表明是一个活的UI
  4. UI布局:组织管理合个UI,一个UI调起另一个UI,自己死掉或藏起来。

构建基本UI能力:React完成的非常不错,通过写JSX能完成一个基本UI的构建。JSX是一个非常好的工程化手段,你第一眼看到它,可难会不爽。但新事物总要给它五分钟!品味一下,你会发现这样做更内聚,更务实的把计算与显示内聚在一个地方,甚至你还可以把css样式以inline sytle的方式写在js文件里。最重要的是它可以把让XML化的组件与js完美混合计算!

在数据绑定:React通过父子组件的props数据通讯协议,可以漂亮的完成初始数据绑定。这个props做得简单而高效,大亮点!

用户交互:React组件被认为自己是一个有限状态机。与用户交互,改变自己的状态(state)。算法根据这些状态,render算法现计算出合适的数据集呈现给用户。这样做的好处是设计范式高度一致。

UI布局,可能需要用到react-router,或者自己写框架。这一块还未研究。

1.3 对比其它方案

React对比其它方案,突出优点是正交化、轻、约定性、务实:

  1. 正交:对比Vue, Angular更正交化,它没有template,大的component就是template。
  2. 轻:对比abobe flex或其它的UI系统是轻,没有复杂的UI OO体系,这也是说明React只是一个目标UI体系的粘合层。
  3. 约定性:约定大于Java仪式感,这也是自Rails之后在风潮。如pure render,最小化无状态state。
  4. 务实:通过JSX来组织表达控件的树形结构,用this.props来传递数据

1. 4 挑战

React是数据驱动式的UI component体系,是一个开放的数据依赖式,非自闭OO对象。它会有以下挑战

  1. render方法可能很大,component显示逻辑是一次性在render里实现的。这里往往有两部分逻辑实现,初次数据绑定,与用户交互之后的算法。
  2. render出一个ReactElement树,但这个树中的一些组件、UI元素因为计算被前移了,这会导致这个树看起来不太完整,进而不太直观。
  3. 虽然可以分解成小的component,构建大的Component可能是个挑战,因为所有逻辑都依赖于外部数据,而外部数据相对不稳定,组件失去了自我边界的保护,非自闭。
  4. 当交互复杂,组件的state也会越来越大,render全局算法会越来越难写。
  5. 把子组件的行为传上来也是一件不显化的事,往往需要把父组件的一个函数作为回调传给子组件。
  6. 大组件往往有多个Page,这几个Page如何交换数据是个很大的挑战

2. 谈谈对Redux的理解

2. 1 独特性

  1. 一个数据层的framework,类似于Baobab。比其好的一点,引入middleware体系,有几个现成的插件redux-thunk, redux-promise,不用但心异步请求的事。虽然说灵活、独立很重要,但全局设计也是 让人放心去用,而不用担心功能缺失和其它风险。
  2. 应用了FP中数据不可变性(immutable),这让追踪数据改变过程有很大提升。也就是其宣扬的时间旅行。这对复杂问题定位是有好处的。
  3. 树形化数据存储,reducer的返回即是其新建,更新、删除过程,树形结构不需要预先定义。同时,reducer也是纯函数,与reactor的render是纯函数呼应。
  4. 强约束(约定),增加了内聚合性。Flux中的action, dispatcher, store比较散,在分层架构是需要的,但内聚性不佳,出现java的仪式感。而redux是数据层很清晰,一个store,更新则dispatch到action,前半段自己想怎么搞就怎么搞(middleware),后半段reducer。reducer约束是不要改oldState,返回newStatew,做到immutable。
  5. 不一样的action:Redux中的action会切得很细,一个传统的Action被切成了三个Action:Loading, GetSuccess, GetError。所以,从这个方面来看Action服务于UI,而非业务逻辑单元。
  6. Redux大量应用FP,经常遇到FP中的curry, trund, promise这些概念,学习成本较高。在middleware层实现,对没有FP经验的人讲不友好。

2.2 置Redux于上下文中

  1. Redux是一个比较薄的数据层。同时,把View同步刷新也做了(redux-react)。
  2. 在传统MVC中,还是有一个controller来做业务逻辑。但Redux硬生生的把一个controller切成二部分:action, reducer。
  3. 理论上,Redux还可以把React组件中的stat的存储也拿过来,比如用户搜索的名称。这样,就可以把过滤算法放到selector中去。但这样好处并不是很大。

2.3 与其它方案对比

  1. 与Baobab对比,两者都是数据管理框架,Baobab提供cursor来方便你对很深层的数据结构进行update。而redux是通过selector函数来做,这种方法会比较晦涩。但比Baobab好的地方,做数据fetch可以通过Redux的middleware来完成。
  2. 与Rails的controller, ActionRecord相比,Redux更多是一种约定,不提供路由级的controller,不提供数据访问cursor。
  3. 接口不超过10个,代码也非常少,但是与之前的MVC框架完全不同。可能最大的问题是没有和react-route打通,在工程化时让人迷茫。

2.4 挑战

  1. Redux应用最大的挑战更多来自设计层面,如何设计action,设计state树形结构。我们只能通过非常少的线索(FP架构思想)去做,这对没有FP经验的团队是一个大挑战。
  2. 通过selector函数从stat树里取数据比较晦涩,并且这个selector里的代码认为是业务逻辑,单独放在selector,业务上不内聚。
  3. middleware层设计:action是一个意图(intent),发送给middleware,让其来实现此意图。但这样做,action比有两义性,一会儿是对象,一会儿是函数。同时FP编程侵入性太大。
  4. 没有与Route结合起来设计,让人很不放心,也不知道如何在不同路由下来做数据与组件的connect。

3. 总结

react + redux是一种典型的FP编程范式实现,而其它框架大多是OO范式。是否选用react+redux开发,需要看是否对FP有掌握或者有一定的架构能力。但单独用react则没有这种要求,当个view来用。

3.1 FP vs OO

FP优缺点
  1. FP的好处是没有OO的复杂仪式感,是沿着数据结构+算法的思路进行抽象和结构化。如果顶层设计做好,代码复用度极高,代码量少。比如要生成一颗树我用迭归算法直接生成,而OO的人往往会用一个Composite模式去定义一个晦涩的类接口。
  2. FP的缺点也是也是面向过程编程的缺点,算法与数据全局化、并且互相耦合,这往往会导致一个强耦合的系统。如果没有做好顶层设计,是难以演进的。
  3. 通过约定和全局的理解,可以减少FP的一些缺点。“约定大于配置”也是框架的主要发展方向。
OO优缺点
  1. OO的好处是分而治之,增量演进。同时有自闭性,语义比较清晰。
  2. 缺点是在表达一些算法时,反而是很困难的。如command模式实现历史回滚就挺麻烦。也这是四人帮的设计模式大多比较难以理解的原因。另外,OO一直有一个对算法复用的问题,ruby语言解决比较好,用mixin很自然。而像C++就用多继承和泛型,个人感觉并不是最好的。

3.2 建议

  1. 有FP经验的或者架构能力比较强,团队人员比较少、能力强,较强适合用react+redux。不然用react+angluar, 或直接用vue。
  2. 过度的OO,搞太多java仪式感确实没有必要。通过架构设计,FP在生产力有着一定的优势。同时对付复杂系统,能更好调测、定位问题。在新时代下,值得尝试。

深入理解React、Redux的更多相关文章

  1. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?

    作者:Wang Namelos链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...

  2. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?(转)

    作者:Wang Namelos 链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎 解答这个问题并不困难:唯一的要求是你熟悉 ...

  3. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  4. react+redux官方实例TODO从最简单的入门(6)-- 完结

    通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...

  5. react+redux官方实例TODO从最简单的入门(1)-- 前言

    刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...

  6. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  7. React + Redux 入坑指南

    Redux 原理 1. 单一数据源 all states ==>Store 随着组件的复杂度上升(包括交互逻辑和业务逻辑),数据来源逐渐混乱,导致组件内部数据调用十分复杂,会产生数据冗余或者混用 ...

  8. 【原】react+redux实战

    摘要:因为最近搞懂了redux的异步操作,所以觉得可以用react+redux来做一个小小的项目了,以此来加深一下印象.切记,是小小的项目,所以项目肯定是比较简单的啦,哈哈. 项目效果图如图所示:(因 ...

  9. webpack+react+redux+es6

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

随机推荐

  1. Spring 表单提交,后台自动封装有集合对象的对象

    from表单: <form action="${pageContext.request.contextPath}/vote/save" method="post&q ...

  2. js解析php返回的json数据无法获取length的问题分析

    1.问题出现的过程,js解析php json_encode 的数据,无法获取长度信息,提示undefined   debug:       首先打印查看了php encode后的数据,返现最外层是一个 ...

  3. 【第四篇】androidEventbus源代码阅读和分析

    1,分析androidEventbus的注册源代码: 我们在使用androidEventbus的第一步是注册eventbus,如下代码: EventBus.getDefault().register( ...

  4. mysql 表连接

    1.子查询是指在另一个查询语句中的SELECT子句. 例句: SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2); 其中,SELECT ...

  5. 在 Visual Studio 2010 中创建 SharePoint 2010 事件接收器

    Microsoft Visual Studio 2010 提供了一个可用于生成事件接收器的项目类型,事件接收器会在 Microsoft SharePoint 2010 网站上选择事件之前或之后执行操作 ...

  6. PHP:var_dump展示不全

    问题:var_dump展示不全,出现省略号 我们使用php的var_dump函数,可以更直观的查看输出结果,包括类型,数量等详细信息.此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值.数 ...

  7. ckediter

    ckediter ##<link rel='stylesheet' href='/css/index.css' /> <script type="text/javascri ...

  8. POJ 3597 种类数 数学+递推

    http://poj.org/problem?id=3597 题目大意:把一个正多边形分成数个三角形或者四边形,问有多少种方案. 思路:http://www.cnblogs.com/Ritchie/p ...

  9. textFiled输入字数的控制问题之—把带输入的拼音也判断了

    一个textFiled,控制只能输入五个字,现在你已经输入了四个字,在输入第五个字的时候,输入一个拼音之后就不能输入后一个拼音,这里把拼音也当成字来判断了,这种情况下就需要_textFiled.mar ...

  10. git clean -fdx

    http://stackoverflow.com/questions/5807137/git-how-to-revert-uncommitted-changes-including-files-and ...