不得不聊聊的react--入门篇

本文为学习笔记,适合入门的童鞋,如有错误,请多多指教。

一、react诞生

Web app的性能瓶颈,主要有以下原因。

(1)Web基于DOM,而DOM很慢。浏览器打开网页时,需要解析文档,在内存中生成DOM结构,如果遇到复杂的文档,这个过程是很慢的。可以想象一下,如果网页上有上万个、甚至几十万个形状(不管是图片或CSS),生成DOM需要多久?更不要提与其中某一个形状互动了。

(2)DOM拖慢JavaScript。所有的DOM操作都是同步的,会堵塞浏览器。JavaScript操作DOM时,必须等前一个操作结束,才能执行后一个操作。只要一个操作有卡顿,整个网页就会短暂失去响应。浏览器重绘网页的频率是60FPS(即16毫秒/帧),JavaScript做不到在16毫秒内完成DOM操作,因此产生了跳帧。用户体验上的不流畅、不连贯就源于此。

(3)网页是单线程的。现在的浏览器对于每个网页,只用一个线程处理。所有工作都在这一个线程上完成,包括布局、渲染、JavaScript执行、图像解码等等,怎么可能不慢?

(4)网页没有硬件加速。网页都是由CPU处理的,没用GPU进行图形加速。

这里我们看到了dom的问题,下面来学习下react做了哪些事情,就大概清楚为什么react解决了以上问题。

优势:

  • 组件可复用性和扩展性好,开发效率提高

  • 前后端渲染模板上的统一,客户端和服务器都可渲染

  • 引入虚拟DOM,每个React组件都拥有一个完整的生命周期,对DOM状态的操作都会批量更新,以期尽可能的减少页面重绘,来追求更好的性能

劣势:

  • 框架100k,本身较大,手机页面基本首屏WIFI/4S,3G/6S,可以考虑客户端缓存

  • 据其他业务反映,无其他劣势,好评一片

框架建议:REACT+后台直出+前端SPA,后续考虑Service Worker、或者上传到cdn减少后续加载

二、基础

  React 可以在浏览器运行,也可以在服务器运行;

`react.js` 是 React 的核心库
`react-dom.js` 是提供与 DOM 相关的功能
`Browser.js` 的作用是将 JSX 语法转为 JavaScript 语法,此步骤应在服务器完成

监听jsx文件到js自动转化方法:我们都知道react其实是以jsx的方式编码,这就涉及由jsx到js的转化,以下为自动转化方式

  • npm install -g react-tools

  • jsx --watch src/ build/

[JSX] (http://facebook.github.io/jsx/) 是一个看起来很像 XML 的 JavaScript 语法扩展。React 可以用来做简单的 JSX 句法转换。

重点一:组件

ReactDOM.render 是 React 的最基本方法

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

ReactDOM.render(
  <HelloMessage name="John" />,
  document.getElementById('example')
);

React 允许将代码封装成组件(component),React.createClass 方法就用于生成一个组件类 HelloMessage 。模板插入 <HelloMessage /> 时,会自动生成 HelloMessage 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。

注意:
1、组件类的第一个字母必须大写,否则会报错。HelloMessage
2、组件类只能包含一个顶层标签,否则也会报错。h1

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
从组件获取真实 DOM 的节点,这时就要用到 ref 属性

重点二:生命周期

组件的生命周期分成三个状态:

  • Mounting:已插入真实 DOM

  • Updating:正在被重新渲染

  • Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

  • componentWillMount()

  • componentDidMount()

  • componentWillUpdate(object nextProps, object nextState)

  • componentDidUpdate(object prevProps, object prevState)

  • componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用

  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

<应用>
动画类:可以采用componentDidMount,利用定时器不断变化形状或者透明度等形态
ajax:可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI

重点三:state

React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。

getInitialState:用于定义初始状态,也就是一个对象
this.state :属性读取
this.setState: 修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件

state和props不同:

this.props 表示那些一旦定义,就不再改变的特性,它们从父组件传递过来,“属于”父组件。
this.state 是会随着用户互动而产生变化的特性。故表单类渲染也需要用state,this.state 是组件私有的,可以通过调用 this.setState()来改变它。当 state 更新之后,组件就会重新渲染自己。

重点四:react编码过程:

  • 第一步:拆分用户界面为一个组件树

  • 第二步: 利用 React ,创建应用的一个静态版本

  • 第三步:识别出最小的(但是完整的)代表 UI 的 state,分析是否为state 。简单地对每一项数据提出三个问题:

    1. 是从父级通过 props 传入的?可能不是 state 。

    2. 不会随着时间改变?可能不是 state 。

    3. 能根据组件中其它 state 数据或者 props 计算出来?不是 state 。

  • 第四步:确认 state 的生命周期,判断哪个组件会改变或者说拥有这个 state 数据模型。

    1. 找出每一个基于那个 state 渲染界面的组件。

    2. 找出共同的祖先组件(某个单个的组件,在组件树中位于需要这个 state 的所有组件的上面)。

    3. 要么是共同的祖先组件,要么是另外一个在组件树中位于更高层级的组件应该拥有这个 state 。

    4. 如果找不出拥有这个 state 数据模型的合适的组件,创建一个新的组件来维护这个 state ,然后添加到组件树中,层级位于所有共同拥有者组件的上面

  • 第五步:添加反向数据流,组件之间经常交互,从父级到子级比较简单,这里说的从子级到父级

相关链接:
中文社区:http://react-china.org/
facebook react官网:http://facebook.github.io/react/

阅读 2.1k

推荐阅读
JavaScript
用户专栏

厶弋的博客

9 人关注
9 篇文章
专栏主页