通往全栈工程师的捷径 —— React

下图是 React 在国内的百度搜索指数,是拿 React 和 Nodejs 做了个对比,可以看出 React 的关注度也已经逼近 nodejs。

虽然在关注总量上 React 还远不及 jQuery 和 Angular 等等,但它的增长幅度超乎你想象,你知道这意味着什么吗?这意味着关注 React,你就比大多数人走在了业界的前沿!

一、什么是react

引用官网的简介,react就是”一个用来构建用户界面的 javascript 库”。

React 起源于 Facebook 的内部项目,因为 FB 对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

和 Backbone、Angular 等 MV* 框架不一样,它只处理 View 逻辑 ,它只处理 View 逻辑,它只处理 View 逻辑。所以如果你喜欢它,你可以很容易的将它接入到现有工程中,然后用 React 重写 HTML 部分即可,不用修改逻辑。

近几年 web 领域的技术革新非常迅速,React 也是一项新技术…话说 React 出来也已经2年了,其实并不算什么新技术了,只是在国内还没有普及开,这篇文章的目的也是帮助大家更快的理解 react 和认识 react 能给我们带来的价值。

React 这么火,那么它到底有什么牛逼的地方?

1、首先,先跟大家描述下 React 最特别的部分,我们来看 JSX——

JSX 使用的是预编译模板,React 提供了一个预编译工具,叫 react-tools,可以通过 npm 命令安装,一般是在开发时期运行,运行后它会启动一个监听程序,实时监听 JSX 源码的修改,然后自动编译为 JS 代码。

大家留意下,render() 方法里的被编译成了 React.createElement(),它这么做,目的就是为了实现虚拟 DOM。

2.接下来我们来了解 React 最大的亮点 ———— 虚拟 DOM。

传统 web app 和 DOM 直接交互,由 App 来控制 DOM 的构建和渲染、元素属性的读写、事件的注册和销毁等等。 当新产品刚上线的时候,这种做法看起来也挺好。但随着产品功能越来越丰富、代码量越来越多、开发团队人员越来越多 —————

一年后,你的代码可能会变成这样。当然,合理的代码规划能够避免这类问题,但团队里难免会有擅长屠宰式编程的同学,分分钟把你代码改的面目全非。

这时,React 的虚拟 DOM 和单项数据流就能很好的解决这个问题。

虚拟 DOM 则是在 DOM 的基础上建立了一个抽象层,我们对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟 DOM,最后再批量同步到 DOM 中。

虚拟 DOM 会使得 App 只关心数据和组件的执行结果,中间产生的 DOM 操作不需要 App 干预,而且通过虚拟 DOM 来生成 DOM,会有一项非常可观收益——-性能。

所有人都知道 DOM 慢,渲染一个空的 DIV,浏览器需要为这个 DIV 生成几百个属性,而虚拟 DOM 只有6个,所以减少不必要的重排重绘以及 DOM 读写能够对页面渲染性能有大幅提升。

那么我们来看看虚拟 DOM 是怎么做的:React 会在内存中维护一个虚拟 DOM 树,当我们对这个树进行读或写的时候,实际上是对虚拟 DOM 进行的。当数据变化时,然后 React 会自动更新虚拟 DOM,然后拿新的虚拟 DOM 和旧的虚拟 DOM 进行对比,找到有变更的部分,得出一个 Patch,然后将这个 Patch 放到一个队列里,最终批量更新这些 Patch 到 DOM 中。

这样的机制可以保证即便是根节点数据的变化,最终表现在 DOM 上的修改也只是受这个数据影响的部分,可以保证非常高效的渲染。

但这样也是有一定的缺陷的——首次渲染大量DOM时因为多了一层虚拟 DOM 的计算,会比 innerHTML 插入方式慢,所以使用时需要确保不要一次性渲染大量 DOM。

几个UI组件的渲染性能对比

3.组件。

一个最基本的 React 组件由数据和 JSX 两个主要部分构成,我们先来看看数据。

这是一个简单单完整的 React 组件【类】,细节大家先不用太在意细节,了解机制就可以。

props 主要作用是提供数据来源,可以简单的理解为 props 就是构造函数的参数。 state 唯一的作用是控制组件的表现,用来存放会随着交互变化状态,比如开关状态等。

JSX 做的事情就是根据 state 和 props 中的值,结合一些视图层面的逻辑,输出对应的 DOM 结构。

前面我们知道了一个简单的组件的构成,但单个的组件肯定不能满足实际需求,我们需要做的是将这些独立的组件进行组装,同时找出共性的部分进行复用。

比如这样一个场景:

我们以这样一个界面为例,可以看出,里面的 <Pub/> <Article/> 都是最细粒度的组件,是可以复用的。 首先,我们来看下 Article 的代码——

这个就是我们分解出来的 Article 组件,它需要2个属性,article 对象和 showImage。article 对象包含图片、地址、标题、描述信息,showImage 是一个布尔类型,用来判断是否需要显示成一个图片。

这个组件本身的实现可以很简单也可以很复杂,但使用者可不关心你的内部实现,使用者关心的是组件需要什么参数就可以了。希望大家在设计模块的时候,也尽可能将组件逻辑对外透明,来减少维护成本。

大家留意一下标虚线的部分,这里复用了 Article 组件。这时的 Article 组件看起来就是一个普通的标签而已,简单吧。

这个是热问组件,也复用了 Article 组件。这就是 React 如丝般顺滑的组件复合。

4.数据流

这个,叫做竹笕,是中日传统禅文化中常见的庭院装饰品,它的构造可简单可复杂,但原理很简单,比如这个竹笕,水从竹笕顶部入口流入内部,并按照固定的顺序从上向下依次流入各个小竹筒,然后驱动水轮转动。如果竹笕是一个组件的话,那么水就是组件的数据流。

在 React 中,数据流是自上而下单向的从父节点传递到子节点,所以组件是简单且容易把握的,他们只需要从父节点提供的 props 中获取数据并渲染即可。如果顶层组件的某个 prop 改变了,React 会递归地向下遍历整棵组件数,重新渲染所有使用这个属性的组件。

这个是前面看到的 Article 题组件,拥有一个叫做 articles 的属性。

在组件内部,可以通过 this.props 来访问 props,props 是组件唯一的数据来源,对于组件来说props 永远是只读的。

组件的属性类型如果不进行声明和验证,那么很可能使用者传给你的属性值或者类型是无效的,那会导致一些意料之外的故障。好在 React 已经为我们提供了一套非常简单好用的属性校验机制——

React 有一个 PropTypes 属性校验工具,经过简单的配置即可。当使用者传入的参数不满足校验规则时,React 会给出非常详细的警告,定位问题不要太容易。

PropTypes 包含的校验类型包括基本类型、数组、对象、实例、枚举——

以及对象类型的深入验证等等。如果内置的验证类型不满足需求,还可以通过自定义规则来验证。 如果某个属性是必须的,在类型后面加上 .isRequired 即可。

5.React 的一大创新,就是把每一个组件都看成是一个状态机,组件内部通过 state 来维护组件状态的变化,这也是 state 唯一的作用。

state 一般和事件一起使用,我们先看 state,然后看看 state 和事件怎样结合。

这是一个简单的开关组件,开关状态会以文字的形式表现在按钮的文本上。

首先看 render 方法,返回了一个 button 元素,给 button 注册了一个事件用来处理点击事件,在点击事件中对 state 的 on 字段取反,并执行 this.setState() 方法设置 on 字段的新值。一个开关组件就完成了。

6.事件。

组件渲染完成后,必须有 UI 事件的支持才能正常工作。React 通过将事件处理器绑定到组件上来处理事件。

React 事件本质上和原生 JS 一样,鼠标事件用来处理点击操作,表单事件用于表单元素变化等,Rreact 事件的命名、行为和原生 JS 差不多,不一样的地方是 React 事件名区分大小写。

比如这段代码中,Article 组件的 section 节点注册了一个 onClick 事件,点击后弹出 alert。

有时候,事件的处理器需要由组件的使用者来提供,这时可以通过 props 将事件处理器传进来。

这个是刚才那个 Article 组件的使用者,它提供给 Article 组件的 props 中包含了一个 onClick 属性,这个 onClick 指向这个组件自身的一个事件处理器,这样就实现了在组件外部处理事件回调。

这是一个 React 组件实现组件可交互所需的流程,render() 输出虚拟 DOM,虚拟 DOM 转为 DOM,再在 DOM 上注册事件,事件触发 setState() 修改数据,在每次调用 setState 方法时,React 会自动执行 render 方法来更新虚拟 DOM,如果组件已经被渲染,那么还会更新到 DOM 中去。

这些是 React 目前支持的事件列表。

7.组件的生命周期

React 的组件拥有一套清晰完整而且非常容易理解的生命周期机制,大体可以分为三个过程:初始化、更新和销毁,在组件生命周期中,随着组件的 props 或者 state 发生改变,它的虚拟 DOM 和 DOM 表现也将有相应的变化。

首先是初始化过程,这里会着重讲,需要充分理解。

组件类在声明时,会先调用 getDefaultProps() 方法来获取默认 props 值,这个方法会且只会在声明组件类时调用一次,这一点需要注意,它返回的默认 props 由所有实例共享。

在组件被实例化之前,会先调用一次实例方法 getInitialState() 方法,用于获取这个组件的初始 state。

实例化之后就是渲染,componentWillMount 方法会在生成虚拟 DOM 之前被调用,你可以在这里对组件的渲染做一些准备工作,比如计算目标容器尺寸然后修改组件自身的尺寸以适应目标容器等等。

接下来就是渲染工作,在这里你会创建一个虚拟DOM用来表示组件的结构。对于一个组件来说,render 是唯一一个必须的方法。render方法需要满足这几点:

  1. 只能通过 this.props 或 this.state 访问数据
  2. 只能出现一个顶级组件
  3. 可以返回 null、false 或任何 React 组件
  4. 不能对 props、state 或 DOM 进行修改

需要注意的是,render 方法返回的是虚拟 DOM。

渲染完成以后,我们可能需要对 DOM 做一些操作,比如截屏、上报日志、或者初始化 iScroll 等第三方非 React 插件,可以在 componentDidMount() 方法中做这些事情。当然,你也可以在这个方法里通过 this.getDOMNode() 方法取得最终生成 DOM 节点,然后对 DOM 节点做爱做的事情,但需要注意做好安全措施,不要缓存已经生成的 DOM 节点,因为这些 DOM 节点随时可能被替换掉,所以应该在每次用的时候去读取。

组件被初始化完成后,它的状态会随着用户的操作、时间的推移、数据更新而产生变化,变化的过程是组件声明周期的另一部分 ——

当组件已经被实例化后,使用者调用 setProps() 方法修改组件的数据时,组件的 componentWillReceiveProps() 方法会被调用,在这里,你可以对外部传入的数据进行一些预处理,比如从 props 中读取数据写入 state。

默认情况下,组件在 setState() 之后,React 会遍历这个组件的所有子组件,进行“灌水”,将 props 从上到下一层一层传下去,并逐个执行更新操作,虽然 React 内部已经进行过很多的优化,这个过程并不会花费多少时间,但是程序员里永远不缺乏长期性能饥渴的同学,不用担心,React 有一个能够解决你性能饥渴的办法—— shouldComponentUpdate() ——有时候,props 发生了变化,但组件和子组件并不会因为这个 props 的变化而发生变化,打个比方,你有一个表单组件,你想要修改表单的 name,同时你能够确信这个 name 不会对组件的渲染产生任何影响,那么你可以直接在这个方法里 return false 来终止后续行为。这样就能够避免无效的虚拟 DOM 对比了,对性能会有明显提升。

如果这个时候有同学仍然饥渴难耐,那么你可以尝试不可变数据结构(用过 mongodb 的同学应该懂)。

组件在更新前,React 会执行 componentWillUpdate() 方法,这个方法类似于前面看到的 componentWillMount() 方法,唯一不同的地方只是这个方法在执行的时候组件是已经渲染过的。需要注意的是,不可以在这个方法中修改 props 或 state,如果要修改,应当在 componentWillReceiveProps() 中修改。

然后是渲染,React 会拿这次返回的虚拟 DOM 和缓存中的虚拟 DOM 进行对比,找出【最小修改点】,然后替换。

更新完成后,React 会调用组件的 componentDidUpdate 方法,这个方法类似于前面 componentDidMount 方法,你仍然可以在这里可以通过 this.getDOMNode() 方法取得最终的 DOM 节点。

香港电影结尾经常看到一个剧情,就是英雄打败了坏人,然后警察出来擦屁股——

componentWillUnmount 除了擦屁股什么也做不了。

你可以在这个方法中销毁非 React 组件注册的事件、插入的节点,或者一些定时器之类。这个过程可能容易出错,比如绑定了事件却没销毁,这个 React 可帮不了你,你自己约的炮,含着泪也要打完。

二、服务端渲染

下面我们来看看 React 怎样结合 nodejs 实现服务端渲染。服务端渲染有多快我就不多说了。

因为有虚拟 DOM 的存在,React 可以很容易的将虚拟 DOM 转换为字符串,这便使我们可以只写一份 UI 代码,同时运行在 node 里和和浏览器里。

var html = React.renderToString(elem);

在 node 里将 react 组件 HTML 渲染为 HTML,一句代码即可。

不过围绕这个 renderToString 我们还要做一些准备工作:

  1. 从后台 server 或数据库等来源拉取数据
  2. 调用 React.renderToString() 方法来生成 HTML
  3. 最后发送 HTML 和数据给浏览器

代码就不贴了,大家自行脑补。

需要注意的是这里的 JSON 字符串中可能出现 </script> 结尾标签或 HTML 注释,可能会导致语法错误,这里需要进行转义。

页面的示例代码本来打算用大家更熟悉的 HTML,但发现代码量太多了,所以换成了 jade 代码,没用过 jade 的同学也顺便了解一下,我也顺便给 jade 打个广告。 这个页面做了这几件事:

  1. 将前面在 action 里生成的 HTML 写到 #container 元素里
  2. 引入必须的 JS 文件
  3. 获取 action 提供的数据
  4. 渲染组件

这就是 React 的服务端渲染,组件的代码前后端都可以复用。

是不是感觉 React 挺牛逼的?还没完!

React 能够用一套代码同时运行在浏览器和 node 里,而且能够以原生 App 的姿势运行在 iOS 和 Android 系统中,即拥有了 web 迭代迅速的特性,又拥有原生 App 的体验。

这个姿势叫做 React-Native。

这是 React 和 React-Native 在 github 上的数据,可以看出 React-Native 也是相当热门——因为 React-Native 能够使 React 的价值最大化,这个价值是什么呢——对业务来说,意味着不需要为了做终端版本就招聘和前端等量人力的终端开发,同时意味着我们成为全栈工程师有了一个捷径。

三.React-Native

了解 iOS 开发的同学都知道,水果公司对应用上架的审核效率实在让人无力吐槽,很多团队上一个版本还没审核结束,下一个版本就已经做好了。而 React-Native 支持从网络拉取 JS,这样 iOS 应用也能够像 web 一样实现快速迭代了。

上图就是 react-native 的调试过程,以 iOS 为例

  1. 启动 xcode build
  2. 在模拟器中按下 Command + D 打开菜单,选择 Debug in Chrome
  3. 在 Chrome dev tools 中调试

四、缺点

当然,react 并不是完美的,在实际使用时你也会发现她的一些缺点,比如:

(如果只是做安卓 app 开发,那么“苹果两件套+开发者证书”不是必须的,在 windows 下面开发即可。)最后,大家在使用 react 开发时,可能会需要安装 React developer tools

最后是一点参考资料

原文:http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=401107957&idx=1&sn=200418877771f656c1a0ab33ad407516&scene=0#wechat_redirect

时间: 2024-10-13 18:40:14

通往全栈工程师的捷径 —— React的相关文章

全栈工程师之路-React Native之扫描二维码

前言 以前开发移动端页面,总会被原生开发各种嫌弃,H5性能太低,动画不流畅,身为一名小前端我能怎么办呢?总是在无人的夜里,心里默默地流泪~ 后来 React Native 出来以后,终于可以翻身农奴把歌唱:哈哈哈,原生的小X人们,等待我 RN 的小皮鞭吧,pia~ 但是那时候若是不懂点 Android 或者 iOS,完全用 RN 开发一个 App,是非常痛苦的. 在尝试一段时间以后,由于实在难以忍受调教各种莫明其妙的报错,让我一度对这项新技能又爱又恨,望而生畏~ 但是最近由于项目上的需求又捡了起

全栈工程师

关键开发技能(硬实力) 一.Git/GitHub,必须掌握如何使用Git来掌握和分享你的代码.Git作为关键技能的第一条,是因为它不仅仅是一个代码管理工具,更是一种推荐的工作方式.它使你能在任何地方进行开发,高效地管理任何大小的项目,通过Git还能与其他团队成员进行分布式工作,大大提升工作效率. 二.至少一门编程语音,JAVA.PHP.C#.Python.Ruby.Perl等,因为大多数核心业务处理都需要这门语言来写.不但要掌握这门语言的语法,还需要非常熟透如何基于这门语言进行项目的架构.设计.

技术栈选择与全栈工程师

很多朋友的第一门语言是一个强类型语言.可能是C/C++/Java/C#. 做到一定年份了,积累了丰富的经验,发现自己好像大多数东西能做,客户端.服务端.手机.游戏,很多场景自己都可以进行开发. 在各种场景下都能开发. 在各种场景下都遇到有力的竞争对手. 竞争对手貌似不少人比自己开发效率高. 类似这样的技术人员,我们可以称之为C蛮. ---------------- C蛮和队长的故事 -------------- C蛮浑身肌肉,手持精金巨斧. 无论看到什么怪物,嗷呜一声吼.狂暴+吹大+高等魔化武器

CSDN日报20170329 ——《“全栈”工程师 请不要随意去做》

[程序人生]"全栈"工程师 请不要随意去做 作者:郭小北 很简单就是最近越来越多的人想做[全栈工程师],他们的目标就是全栈,他们才入行短短1-2年,甚至刚从培训班出来:我的目标是做全栈,我啥都要学会,啥都会写,这样我就是大牛了,可以挣大钱,就算创业,我也不用招那么多人,一个人搞定一个产品,融资上市 ,CEO 白富美,balabala... [Web 前端]关于 PWA 落地问题的思考 作者:Horky PWA 是最近一个热门话题,很多开发同学都在尝试落地,其中也有些还在犹豫.这篇文章主

努力成长为一只全栈工程师

完全转到互联网行业来之后,就一直在读书,内容都是计算机领域的,除了读书还看视频,是关于计算机基础理论课的,应用方面的就不看视频了,太贫太慢,不如文档来得快.看书也尽量挑进阶一点的,比如书名包含“性能”.“进阶”.“设计模式”.“算法”,其实这些对一个互联网领域的熟练工来说,应该也是标配了.看这些书的目的就是为了让自己更专业,能够解决更多的问题,写代码写得更明白. 换到新公司这几个月以来,除了觉得自己要恶补知识之外,有两点让自己非常庆幸,一是原来在大公司的经历让自己已经足够职业了,清楚地知道工作对

你是否应该成为一名全栈工程师?

本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/01/become-full-stack-developer Asaf Yigal是Logz.io的联合创始人与产品副总裁.在Logz.io之前,Asaf与他人联合创立了Currensee,这是一个社会化交易平台,后来在2013年被OANDA收购.在Currensee之前,Asaf在Akorri负责管理和开发一款端到端的性能监控平台,在Onaro开发过一款存储资源管理平台.后

转:全栈工程师的知识栈列表

from: http://blog.csdn.net/caopeng26/article/details/52235883 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 通往互联网架构师之路—全栈工程师 1.首先我们看什么是架构师?架构师应该具备哪些能力? 大家都知道很多公司都有架构师这个职位,但是我想告诉大家的是看一个人是不是架构师不是看职位,而是看他所具备的能力以及正在做的事,所以有架构师头衔的人不一定具备架构师的能力,而不是架构师的人却在做着架构师的工作. 2.架

全栈工程师要掌握的技术要点

关键开发技能(硬实力): Git / GitHub —— 你必须掌握如何使用Git来管理和分享你的代码.把Git作为关键技能的第一条,是因为它不仅仅是一个代码管理工具,更是一种推荐的工作方式.它使你能在任何地方进行开发,高效地管理任何大小的项目,通过Git你还能与其他团队成员进行分布式协作,大大提升工作效率.通过GitHub,还能将你与世界所有的开发者联系在一起. 至少一门编程语言 —— 你需要精通至少一门编程语言,JAVA .PHP.C#.Python.Ruby.Perl 等,因为你的大多数核

2019年如何成为全栈工程师?

2019年到了,每个前端工程师都有一颗全栈的心,很多读者私信我,怎么才能晋升为全栈工程师.这里给大家解答一下大概路线. 随着前端能做的事情越来越多,前端的知识体系也越来越复杂,面对密集的知识点,一口气吃不成胖子的,所以,制定好一个合理的学习路线是必不可少的了. 1. 前端 万丈高楼平地起,学习前端也是一样,没有基础知识做地基,Html/Css/JavaScript自不必说,重中之重,务必得学的扎实. 选择框架的确很难以抉择,React用户量遥遥领先,一定是极好的,但是,我建议大家选择Vue,更快