React 背景知识
React 是一个用于构建用户界面的 JavaScript 库,主要用于构建 UI,而不是一个 MVC 框架,但可以使用 React 作为 MVC 架构的 View 层轻易的在已有项目中使用,它是一个用于构建用户界面的 JavaScript 库,起源于 Facebook 的内部项目,用来架设 Instagram 的网站,于 2013 年 5 月开源。React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
以前没有 ajax 技术的时候,web 页面从服务端整体渲染出 html 输出到浏览器端进行渲染,同样的,用户的一个改变页面的操作也会刷新整个页面来完成。直到有了 ajax 出现,实现页面局部刷新,带来的高效和分离让 web 开发者们惊叹不已。但随之而来的问题是,复杂的用户交互及展现需要通过大量的 DOM 操作来完成,这让页面的性能以及开发的效率又出现了新的瓶颈。
时至今日,谈到前端性能优化,减少 DOM 元素、减少 reflow 和 repaint、编码过程中尽量减少 DOM 的查询等手段是大家耳熟能详的。而页面任何UI的变化都是通过整体刷新来完成的。幸运的是,React 通过自己实现的 DOM Diff 算法,计算出虚拟页面当前版本和新版本之间的差异,最小化重绘,避免不必要的 DOM 操作,解决了这两个公认的前端性能瓶颈,实现高效 DOM 渲染。
我们知道,频繁的操作 DOM 所带来的性能消耗是很大的,而 React 之所以快,是因为它不直接操作 DOM,而是引进虚拟 DOM 的实现来解决这个问题
对于页面的更新,React 通过自己实现的 DOM Diff 算法来进行差异对比、差异更新,反映到页面上就是只重绘了更新的部分,从而提高渲染效率。
备注:以下性能阐述参考自尤雨溪。
对于 React 的性能方面,想啰嗦几句:
1. React 从来没有说过 “React 比原生操作 DOM 快”。React 的基本思维模式是每次有变动就整个重新渲染整个应用。如果没有 Virtual DOM,简单来讲就是直接重置 innerHTML。
2. 在比较性能的时候,要分清楚初始渲染、小量数据更新、大量数据更新这些不同的场合。
3. 不要天真地以为 Virtual DOM 就是快,diff 不是免费的,Virtual DOM 真正的价值从来都不是性能,而是它
1) 为函数式的 UI 编程方式打开了大门;
2) 可以渲染到 DOM 以外的其他场景,如 backend、native。
组件化
在业务开发中,遇到公共的模板部分,我们不得不将模板和规定的数据格式耦合在一起来实现组件。而在 React 中,我们可以使用 JSX 语法来封装组件,将组件的结构、数据逻辑甚至样式都聚合在一起,更加简单、明了、直观的定义组件。
有了组件化的实现,我们可以很直观的将一个复杂的页面分割成若干个独立组件,再将这些独立组件组合完成一个复杂的页面。这样既减少了逻辑复杂度,又实现了代码的重用。
React 基础
模板
JSX
上一节的代码, HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写
JSX的好处:
1.使用JSX语法来封装组件有什么好处:
1)熟悉的代码
2)更加语义化
3)更加抽象且直观
2.几个注意点:
1)render的方法中return的顶级元素只能是一个;
2)如果要定义样式的时候,不能这样去写 // 不要出现类似的错误,style=“opacity:{this.state.opacity};”
3)使用 className 和 htmlFor 来替代对应的class 和 for
提示:关于组件化的话题,感兴趣的话可以继续关注Vuejs、Web components等对组件的写法。/**随着更为复杂的多端环境的出现,组件标准化还有着更大的想象空间,React的组件定义不是终点,也不一定是标准,但会在组件化的道路上留下深刻de影响。**/
JSX 基本语法:
上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。
JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员。
React is awesome
, ]; ReactDOM.render(组件
1.概念
React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类
2.代码示例
Hello {this.props.name}
; } }); ReactDOM.render(this.props.children
this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点
PropTypes
组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求。
{this.props.title}
; } }); var data = “123”; ReactDOM.render(错误示范: ,document.body ); @H_301_56@
getDefaultProps
getDefaultProps 方法可以用来设置组件属性的默认值
获取真实的 DOM 节点
组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
this.state
组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。
{value}
@H_301_56@ ); } }); ReactDOM.render(,document.body); @H_301_56@组件 API
组件的7个方法:
设置状态:setState;
替换状态:replaceState;
设置属性setProps;
替换属性replaceProps;
强制更新:forceUpdate;
获取DOM节点:getDOMNode;
判断组件挂载状态:isMounted。
组件生命周期
初始化
getDefaultProps:设置默认性的值
getInitialState:设置初始的状态
componentWillMount:(组件即将被装载)
render(渲染)
componentDidMount:组件已经被装载,只会在第一个组件被调用的时候出发
运行中
componentWillReceiveProps 在组件将要接收到属性的时候,接收属性前
shouldComponentUpdate 在接收到新的 props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用
componentWillUpdate render 触发之前,更新
render 渲染
componentWillUnmount 在组件从 DOM 中移除的时候立刻被调用
销毁
componentWillUnmount 在组件从 DOM 中移除的时候被立刻调用
因为 React 组件样式是一个对象第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象
Ajax
上面代码没有使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。