问题一:ReactJS组件难以在复杂交互页面中复用

ReactJS中的最小复用单位是组件。ReactJS的组件比AngularJS的Controller和View 要轻量些。 每个组件只需要前端开发者提供一个 render 函数,把 props 和 state 映射成网页元素。

这样的轻量级组件在渲染简单静态页面时很好用, 但是如果页面有交互,就必须在组件间传递回调函数来处理事件。

我将在《More than React(二)组件对复用性有害?》中用原生DHTML API、ReactJS和Binding.scala实现同一个需要复用的页面,介绍Binding.scala如何简单实现、简单复用复杂的交互逻辑。

问题二:ReactJS的虚拟DOM 算法又慢又不准

ReactJS的页面渲染算法是虚拟DOM差量算法。

开发者需要提供 render 函数,根据 props 和 state 生成虚拟 DOM。 然后 ReactJS 框架根据 render 返回的虚拟 DOM 创建相同结构的真实 DOM.

每当 state 更改时,ReacJS 框架重新调用 render 函数,获取新的虚拟 DOM 。 然后,框架会比较上次生成的虚拟 DOM 和新的虚拟 DOM 有哪些差异,然后把差异应用到真实DOM上。

这样做有两大缺点:

  1. 每次 state 更改,render 函数都要生成完整的虚拟 DOM. 哪怕 state 改动很小,render函数也会完整计算一遍。如果 render 函数很复杂,这个过程就白白浪费了很多计算资源。
  2. ReactJS框架比较虚拟DOM差异的过程,既慢又容易出错。比如,假如你想要在某个 <ul>列表的顶部插入一项 <li> ,那么ReactJS框架会误以为你修改了 <ul> 的每一项<li>,然后在尾部插入了一个 <li>

这是因为 ReactJS收到的新旧两个虚拟DOM之间相互独立,ReactJS并不知道数据源发生了什么操作,只能根据新旧两个虚拟DOM来猜测需要执行的操作。 自动的猜测算法既不准又慢,必须要前端开发者手动提供 key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法或者 componentWillUpdate 等方法才能帮助 ReactJS 框架猜对。

我将在《More than React(三)虚拟DOM已死?》中比较ReactJS、AngularJS和Binding.scala渲染机制,介绍简单性能高的Binding.scala精确数据绑定机制。

问题三:ReactJS的HTML模板功能既不完备、也不健壮

ReactJS支持用JSX编写HTML模板。

理论上,前端工程师只要把静态HTML原型复制到JSX源文件中, 增加一些变量替换代码, 就能改造成动态页面。 理论上这种做法要比Cycle.js、Widok、ScalaTags等框架更适合复用设计师提供的HTML原型。

不幸的是,ReactJS对HTML的支持残缺不全。开发者必须手动把classfor属性替换成classNamehtmlFor,还要把内联的style样式从CSS语法改成JSON语法,代码才能运行。 这种开发方式下,前端工程师虽然可以把HTML原型复制粘贴到代码中,但还需要大量改造才能实际运行。 比Cycle.js、Widok、或者、ScalaTags省不了太多事。

除此之外,ReactJS还提供了propTypes机制校验虚拟DOM的合法性。 然而,这一机制也漏洞百出。 即使指定了propTypes,ReactJS也不能在编译前提前发现错误。只有测试覆盖率很高的项目时才能在每个组件使用其他组件时进行校验。 即使测试覆盖率很高,propTypes仍旧不能检测出拼错的属性名,如果你把onClick写成了onclick, ReactJS就不会报错,往往导致开发者额外花费大量时间排查一个很简单的bug。

我将在《More than React(四)HTML也可以编译?》中比较ReactJS和Binding.scala的HTML模板,介绍Binding.scala如何在完整支持XHTML语法的同时静态检查语法错误和语义错误。

问题四:ReactJS与服务器通信时需要复杂的异步编程

ReactJS从服务器加载数据时的架构可以看成MVVM(Model–View–ViewModel)模式。 前端工程师需要编写一个数据库访问层作为Model,把ReactJS的state当做ViewModel,而render当做View。 Model负责访问数据库并把数据设置到state(即View Model)上,可以用Promise和fetch API实现。 然后,render,即View,负责把View Model渲染到页面上。

在这整套流程中,前端程序员需要编写大量闭包组成的异步流程, 设置、访问状态的代码五零四散, 一不小心就会bug丛生,就算小心翼翼的处理各种异步事件,也会导致程序变得复杂,既难调试,又难维护。

为什么 ReactJS 不适合复杂的前端项目?的更多相关文章

  1. 前后端分离之前端项目构建(grunt+require+angular)

    前言 前段时间做了一个项目,前端开发页面,然后把代码给到后端同学,后端同学通过vm再来渲染页面.后来才发现,这种方式简直是太low了,因为前端代码在服务端同学那里,每次前端需要更改的时候都需要去到服务 ...

  2. 使用gulp来构建一个前端项目

    什么是gulp? gulp是一个前端项目构建工具,是自动化项目的构建利器,它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成.你可以使用gulp及其插件对你的项目代码 ...

  3. Github前端项目排名

      Github前端项目排名(2016-04-04) 一.前言 近几年前端技术日新月异,从 RequireJS 到 AngularJS 再到 React,似乎每天都有新的技术诞生.而大神们总能第一时间 ...

  4. 如何打造一个"逼格"的web前端项目

    最近利用空余的时间(坐公交车看教程视频),重新了解了前后端分离,前端工程化等概念学习,思考如何打造一个“逼格”的web前端项目. 前端准备篇 前端代码规范:制定前端开发代码规范文档. PS:重中之中, ...

  5. 在Vue&Element前端项目中,对于字典列表的显示处理

    在很多项目开发中,我们为了使用方便,一般都会封装一些自定义组件来简化界面的显示处理,例如参照字典的下拉列表显示,是我们项目中经常用到的功能之一,本篇随笔介绍在Vue&Element前端项目中如 ...

  6. 大型前端项目 DevOps 沉思录 —— CI 篇

    摘要 DevOps 一词源于 Development 和 Operations 的组合,即将软件交付过程中开发与测试运维的环节通过工具链打通,并通过自动化的测试与监控,减少团队的时间损耗,更加高效稳定 ...

  7. 用gulp构建你的前端项目

    前言 前端技术发展日新月异,随着模块化.组件化的提出,前端变得越来越复杂,静态资源越来越多,那么对静态资源的处理,如压缩,合并,去掉调试信息.. 如果还是人工去处理,效率非常之低且还容易出错,于是自动 ...

  8. 前端项目构建工具---Grunt

    什么是Grunt? grunt是javascript项目构建工具,在grunt流行之前,前端项目的构建打包大多数使用ant.(ant具体使用 可以google),但ant对于前端而言,存在不友好,执行 ...

  9. [front]有效开展一个前端项目

    今天的前端如果没有用到 npm,效率是比较低的:所以要从使用的工具来讲. 1. 一切都依赖于 nodejs: 下载一个 linux 的源码包就可以开始安装了. $ wget https://nodej ...

随机推荐

  1. js的事件循环机制和任务队列

    上篇讲异步的时候,提到了同步队列和异步队列的说法,其实只是一种形象的称呼,分别代表主线程中的任务和任务队列中的任务,那么此篇我们就来详细探讨这两者. 一.来张图感受一下 如果看完觉得一脸懵逼,请继续往 ...

  2. Redis的集群安装以及rehash重新迁移教程指南

    1. Redis的cluster集群 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最核心的目标有三个: 性能:这是Redis赖以生存的看家本领,增加集群 ...

  3. 哈工大LTP语言分析:分词、词性标注、句法分析等

    1. LTP介绍和安装 LTP语言云官网  在线演示 | 语言云(语言技术平台云 LTP-Cloud) 安装LTP的python接口包 $ sudo pip install pyltp 模型文件下载 ...

  4. 错误:XMLHttpRequest cannot load

    原因:Chrome浏览器不支持本地ajax访问,具体就是ajax不能访问file 有3种解决办法:http://frabbit2013.blog.51cto.com/1067958/1254285 其 ...

  5. C# OPC UA服务器 OPC UA网关 三菱 西门子 欧姆龙 Modbus转OPC UA 服务器 可配置的OPC UA服务器网关 HslSharp软件文档

    前言 本文将使用一个基于开源项目HslCommunication创建的OPC UA网关,方便通过配置创建一个OPC UA的网关中心.具体的操作及支持的设备信息项目参照下面: 开源项目HslCommun ...

  6. iOS中数组遍历的方法及比较

    数组遍历是编码中很常见的一种需求,我们来扒一拔iOS里面都有什么样的方法来实现,有什么特点. 因为ios是兼容C语言的,所以c语言里面的最最常见的for循环遍历是没有问题的. 本文中用的数组是获取的系 ...

  7. ubuntu安装 tensorflow GPU

    安装支持GPU的tensorflow前提是正确安装好了 CUDA 和 cuDNN. CUDA 和 cuDNN的安装见 Nvidia 官网和各种安装教程,应该很容易,重点是要选准了支持自己GPU的 CU ...

  8. 64位系统下注册32位dll、ax文件

    64位系统下注册32位dll.ax文件. 换了64位系统遇到的新问题,目前常用的影音处理软件多数为32位. 注册这些32的滤镜会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以 ...

  9. 自动化测试入门指南(3)-- 入门demo

    按照 自动化测试入门指南(2)-- 环境搭建搭建好环境后,我们继续一步步实现一个简单的入门例子 Step0. 安装Firefox浏览器(http://pan.baidu.com/s/1c00bw8g中 ...

  10. log4j的使用配置

    1.与spring整合,web.xml中配置详情 <!-- 加载log4j的配置文件log4j.properties --> <context-param> <param ...