首页 > 技术文章 > 深入浅出react

mawn 2018-05-18 16:55 原文

1,新建项目

为了方便安装一个初始化简单的react组件,我们可以先通过npm 来安装create-react-app 

 

npm install --global create-react-app 

create-react-app first_react_app 

注意:create-react-app默认的是npm镜像  由于npm属于国外镜像,有时候安装会很慢。解决办法

通过换源:npm config set registry https://registry.npm.taobao.org  默认设成淘宝镜像

检验是否换源成功:npm info express或者npm config get registry

 

启动项目

npm start

 

1.2增加一个新的 React组件 

import React, { Component } from 'react';

class ClickCounter extends Component {
  constructor(props) {
    super(props)
    this.onClickButton = this.onClickButton.bind(this);
    this.state = { count: 0 }
  }
  onClickButton() {
    this.setState({
      count: this.state.count + 1
    })

  }
  render() {
    const { count } = this.state
    return (
      <div>
        <div>
          <button onClick={this.onClickButton}>大师马快点我</button>
        </div>
        <p>
          你点了{count}次
          </p>
      </div>

    )
  }
}
export default ClickCounter

 1.3 react工作方式

   实现一个点击计数事件jq是如何工作的 (我就不上代码了就是jq的基本点击事件)

 在 jQuery 的解决方案中,首先根据 css 规则找到 id 为 clickCount 的按钮,挂上 一 个匿名事件处理函数,在事件处理函数中,选中那个需要被修改的 DOM 元素,读取其 中的文本值,加以修改,然后修改这个 DOM 元素 。选中一些 DOM 元素,然后对这些元素做一些操作,这是一种最容易理解的开发模 式 。 jQuery 的发明人 John Resig 就是发现了网页应用开发者的这个编程模式,才创造出 了 jQuery,其一 问世就得到普遍认可,因为这种模式直观易懂 。 但是,对于庞大的项目, 这种模式会造成代码结构复杂,难以维护,每个 jQuery 的使用者都会有这种体会 。

 

打一个比方, React是一个聪明的建筑工人,而 jQuery是一个比较傻的建筑工人, 开发者你就是一个建筑的设计师,如果是 jQuery 这个建筑工人为你工作,你不得不事无 巨细地告诉 jQuery“如何去做”,要告诉他这面墙要拆掉重建,那面墙上要新开一个窗户, 反之,如果是 React这个建筑工人为你工作,你所要做的就是告诉这个工人“我想要什 么样子”,只要把图纸递给 React这个工人,他就会替你搞定一切,当然他不会把整个建 筑拆掉重建,而是很聪明地把这次的图纸和上次的图纸做一个对比,发现不同之处,然 后只去做适当的修改就完成任务了 。

显而易见, React 的工作方式把开发者从繁琐的操作中解放出来,开发者只需要着重 “我想要显示什么”,而不用操心“怎样去做” 。

这种新的思维方式,对于一个简单的例子也要编写不少代码,感觉像是用高射炮打 蚊子,但是对于一个大型的项目,这种方式编写的代码会更容易管理,因为整个 React 应用要做的就是渲染,开发者关注的是渲染成成什么样子,而不用关心如何实现增量 渲染。

React 的理念 ,归结为一个公式,就像下面这样 : UI=render(data)

让我们来看看这个公式表达的含义,用户看到的界面( UI),应该是一个函数(在这 里叫 render)的执行结果,只接受数据( data)作为参数。 这个函数是一个纯函数,所谓 纯函数,指的是没有任何副作用,输出完全依赖于输入的函数,两次函数调用如果输人 相同,得到的结果也绝对相同 。 如此一来,最终的用户界面,在 render 函数确定的情况 下完全取决于输入数据 。

对于开发者来说,重要的是区分开哪些属于 data,哪些属于 render,想要更新用户 界面,要做的就是更新 data,用户界面自然会做出响应,所以 React实践的也是“响应 式编程”( Reactive Programming)的思想,这也就是 React 为什么叫做 React 的原因 。

 

Virtual DOM

既然 React应用就是通过重复渲染来实现用户交互,你可能会有 一个疑虑:这样的 重复渲染会不会效率太低了呢?毕竟,在 jQuery 的实现方式中,我们可以清楚地看到每 次只有需要变化的那一个 DOM 元素被修改了;可是,在 React 的实现方式中,看起来每 次 render 函数被调用,都要把整个组件重新绘制一次,这样看起来有点浪费 。

事实并不是这样, React利用 Virtual DOM,让每次渲染都只重新渲染最少的 DOM 元素。

要了解 Virtual DOM,就要先了解 DOM, DOM 是结构化文本的抽象表达形式,特

定于 Web 环境中,这个结构化文本就是 HTML 文本, HTML 中的每个元素都对应 DOM 中某个节点,这样,因为 HTML 元素的逐级包含关系, DOM 节点自然就构成了一个树 形结构,称为 DOM 树 。

浏览器为了渲染 HTML 格式的网页,会先将 HTML 文本解析以构建 DOM 树,然后 根据 DOM 树渲染出用户看到的界面,当要改变界面内容的时候,就去改变 DOM 树上的 节点。

Web 前端开发关于性能优化有一个原则 :尽量减少 DOM 操作 。 虽然 DOM 操作也只 是一些简单的 JavaScript语句,但是 DOM 操作会引起浏览器对网页进行重新布局,重新 绘制,这就是一个比 JavaScript语句执行慢很多的过程 。

如果使用 mustache 或者 hogan 这样的模板工具,那就是生成 HTML 字符串塞到网页 中,浏览器又要做一次解析产生新的 DOM 节点,然后替换 DOM 树上对应的子树部分, 这个过程肯定效率不高 。 虽然 JSX 看起来很像是一个模板,但是最终会被 Babel 解析为 一条条创建 React组件或者 HTML 元素的语句 ,神奇之处在于, React并不是通过这些语 句直接构建 DOM 树,而是首先构建 Virtual DOM。

既然 DOM 树是对 HTML 的抽象,那 Virtual DOM 就是对 DOM 树的抽象 。 Virutal DOM 不会触及浏览器的部分,只是存在于 JavaScript 空间的树形结构,每次自上而下 渲 染 React组件时,会对比这一次产生的 Virtual DOM 和上一次渲染的 Virtual DOM,对比 就会发现差别,然后修改真正的 DOM 树时就只需要触及差别中的部分就行 。

以 ClickCounter为例,一开始点击计数为 0,用户点击按钮让点击计数变成 l,这一 次重新渲染, React通过 Virtual DOM 的对比发现其实只是 id为 clickCount 的 span元素 中内容从0变成了 l而已:

<span id=” clickCount” >{this.state.count}</span> React发现这次渲染要做的事情只是更换这个 span元素的内容而已,其他 DOM 元

素都不需要触及,于是执行类似下面的语句,就完成了任务:

document.getElementByld (”clickCount”) .innerHTML = ”1”;

 

jq方式造成的代码纠缠

使用 React 的方式,就可以避免构建这样复杂的程序结构,无论何种事件,引发的 都是 React 组件的重新渲染,至于如何只修改必要的 DOM 部分,则完全交给 React 去操 作,开发者并不需要关心, 

 

 

推荐阅读