0. React介绍

0.1 什么是React?

React(有时称为React.js 或ReactJS)是一个为数据提供渲染HTML视图的开源JavaScript库。

它由FaceBook、Instagram和一个由个人开发者和企业组成的社群维护,现在国外比较流行的Facebook、Imgur、Airbnb、uber、Instagram,国内的美团、阿里、大搜车、去哪儿等都在使用React技术。

logo是个原子,中间是原子核,旁边是3个电子的移动轨迹。

0.2 FB为什么推出React?

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

React是解决什么问题的,在官网可以找到这样一句话:

We built React to solve one problem: building large applications with data that changes over time.

数据变化会带来两个问题,大量的DOM操作(自动操作DOM),逻辑及其复杂(状态和内容对应起来 )

0.3 React历史

React是由FaceBook的工程师Jordan Walke创建的,是受到php的HTML组件库XHP影响,React在11年时,刚开始是部署在FaceBook的newsfeed;

随后在12年时部署于Instagram,于13年5月在JSConf US宣布开源

14年成为facebook第一个在Github上达到1万star的旗舰开源项目,

15年3月在JSConf,FaceBook发布了React Native,可以使用React来构建nativeApp,并提出自己的理念“learn once,write anywhere”。

16年4月,发布V15正式版本,但是依然不够稳定,这毕竟是最新的技术。

0.4 React特点

声明式设计:采用声明范式,可以轻松描述应用

高效:通过对DOM的模拟,最大限度减少与DOM的交互

灵活:可以方便的搭配其它库来使用

JSX:是js语法的扩展

组件:构建组件,方便复用

单向相应的数据流

0.5 如何学习React

中文社区:http://reactjs.cn/

gitbook:https://www.gitbook.com/book/hulufei/react-tutorial/details

菜鸟教程:http://www.runoob.com/react/react-tutorial.html

书籍:React引领未来的用户界面开发框架(资料中有pdf电子书)

1.认识React

1.1 概述

1.1.1核心思想

React的核心思想是:封装组件。

各个组件维护自己的状态和UI,当状态改变,自动重新绘制整个组件。

1.1.2 核心概念

React中的核心概念:

概念1:组件

概念2:JSX

JavaScriptXml,不是新语言,也没有改变js的语法,只是对js的扩展,

使用React,建议使用JSX语法,原生js也可以,但是由于JSX在定义类似HTML这种树形结构时,十分简单明了,所欲推荐使用JSX语法。

概念3:Virtual DOM

如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个虚拟 DOM,组件 DOM 结构就是映射到这个虚拟 DOM 上,React 在这个虚拟 DOM 上实现了一个 diff 算法,当要更新组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的 DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个虚拟 DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多。

前面提到 virtual DOM 和真实的 DOM 有着不用的语义, 但同时也有明显不同的 API。

DOM 树上的节点被称为元素, 而 virtual DOM 是完全不同的抽象, 叫做 components。

component 的使用在 React 里极为重要, 因为 components 的存在让计算 DOM diff 更高效

举例:

比如说,现在你的list是这样,
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
你想把它变成这样
<ul>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
通常的操作是什么?
先把0, 1,2,3这些Element删掉,然后加几个新的Element 6,7,8,9,10进去,这里面就有4次Element删除,5次Element添加。
而React会把这两个做一下Diff,然后发现其实不用删除0,1,2,3,而是可以直接改innerHTML,然后只需要添加一个Element(10)就行了,这样就是4次innerHTML操作加1个Element添加,比9次Element操作快多了!

概念4:Data Flow

单向数据绑定。是指数据更新后会自动渲染到页面,避免在业务中频繁的DOM操作。

2. 搭建React开发环境

2.1 依赖

依赖三个库: react.js 、react-dom.js 和 Browser.js ;

它们必须首先加载。其中,react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能,Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,

2.2 创建模板文件

上面代码有两个地方需要注意。首先,最后一个 <script> 标签的 type 属性为 text/babel 。这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel"

3. Hello React

3.1. 开始

创建1.html

  ReactDOM.render(
<h1> hello React </h1>, document.getElementById('example')
);

3.2. render方法介绍

ReactDOM.render(

<h1>Hello, world!</h1>,

document.getElementById('example')

);

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点

4. JSX语法

4.1 基本语法规则

遇到HTML标签(以<开头),就用HTML来解析;遇到代码块(以{开头)就用js来解析

JSX允许使用html语法来创建js对象,拿创建a标签为例,如果使用原生js,是这样的:

React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')

当使用jsx语法时,就变成了这样:

<a href="https://facebook.github.io/react/">Hello!</a>

JSX的基本语法规则:

接下来,创建2.html,验证上述语法。

 var names = ['daxu','dongdong','wenhua'];
ReactDOM.render(
<div>
{
names.map(function (name) {
return <div> hello {name}</div>
})
}
</div>,
document.getElementById('example')
)

  

细心的同学会发现,上边的代码运行时,会有个警告,是因为:

React为了方便DOM渲染,对于每个东西产生时都希望有一个单独的key,我们上边没有设置,所以会有警告,这里先不管它。

4.2  JavaScript表达式

我们可以在JSX中使用JavaScript表达式,表达式写在{}中,比如说:创建3.html

 var arr = [
<h1>react is awesome</h1>,
<h2>let's start to learn!</h2>
]
ReactDOM.render(
< div >
{/* 注释必须卸载花括号中*/}
<h1>{2+3}</h1>
<h2>{3 == 2?'true':'false'}</h2>
{/*如果在花括号中执行数组,数组会自动展开所有成员*/}
{arr}
</div >,document.getElementById('example')
)

  

5 组件

5.1 创建并使用组件

React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类

创建4.html

  

上面代码中,变量 HelloMsg 就是一个组件类。模板插入 < HelloMsg  /> 时,会自动生成 HelloMsg 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。

注意,组件类的第一个字母必须大写,否则显示会有问题,比如HelloMessage不能写成helloMessage。另外,组件类只能包含一个顶层标签,否则也会有问题。

在上述代码上稍作修改:

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 <HelloMsg name="daxu"> ,就是 HelloMsg 组件加入一个 name 属性,值为 daxu。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取。上面代码的运行结果如下。

    var HelloMsg = React.createClass({
render: function () {
return <div><h1> hello {this.props.firstname+this.props.name}</h1> <p>come on!</p></div>;
}
})
ReactDOM.render(
<HelloMsg name='daxu' firstname='zhao'/>,document.getElementById('example')
);

  

5.2 认识props

5.3 常用方法

this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点

这里需要注意, this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined ;如果有一个子节点,数据类型是 object ;如果有多个子节点,数据类型就是 array 。所以,处理 this.props.children 的时候要小心。

React 提供一个工具方法 React.Children 来处理 this.props.children 。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是 object

创建5.html

var MyList = React.createClass({
render: function () {
return(
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>
})
}
</ol>
);
}
});
ReactDOM.render(
<MyList>
<span>lesson1</span>
<span>lesson2</span>
<span>lesson3</span>
</MyList>,
document.getElementById('example')
);

  

5.3 复合组件

我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。

以下实例我们实现了输出网站名字和网址的组件:

创建6.html

6、VDOM

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

但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等

7、state

7.1 认识state

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

具体实现起来,React里有个state,只要更新组件的state,然后根据state重新渲染用户界面(不要操作DOM),React来决定如何最高效的更新DOM。

7.2使用场合

针对text field的变化(用户输入)、服务器请求做出响应时,才需要用到state。

7.3 如何使用

方法介绍:

方法1:getInitialState  定义初始状态,也就是一个对象

方法2:setState 可以获取getInitialState中定义的对象,如果调用setState修改了状态值,每次修改后,都将自动调用this.render方法,再次渲染组件

7.4 案例

    var LikeButton = React.createClass({
getInitialState: function () {
return {liked:false};
},
handlerClick: function (event) {
this.setState({liked:!this.state.liked});
},
render: function () {
var text = this.state.liked?'like':'do not like';
return (
<p onClick={this.handlerClick}>
You {text} this.click to toggle!
</p>
);
}
})
ReactDOM.render(
<LikeButton />,document.getElementById('example')
)

  

上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

8、组件的生命周期

8.1 生命周期的状态

Mounting 已经插入真是DOM

Updating 正在被重新渲染

Unmounting 已经移出DOM

8.2 状态的处理函数

React 为每个状态都提供了两种处理函数:

1、  will 函数在进入状态之前调用

2、  did 函数在进入状态之后调用,

三种状态共计五种处理函数:

  • § componentWillMount() 准备插入
  • § componentDidMount()  已经插入
  • § componentWillUpdate(object nextProps, object nextState) 准备更新
  • § componentDidUpdate(object prevProps, object prevState) 已经更新
  • § componentWillUnmount() 准备从DOM中移除。

8.3 案例分析

    var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
},
componentWillMount: function () {
console.log('准备加入DOM');
},
componentDidMount: function () {
console.log('已经加入DOM');
this.timer = setInterval(function () {
var op = this.state.opacity;
op-=0.5;
if(op < 0.1)
{
op = 1.0;
};
this.setState({
opacity: op
});
}.bind(this),1000);
},
render: function () {
return(
<div style={{opacity:this.state.opacity}}>
hello {this.props.name}
</div>
)
}
}
)
ReactDOM.render(<Hello name='daxu'/>,document.getElementById('example'));

  

9、使用ref和state来实现一个乘法计算器

效果图如下:

    var LianXi = React.createClass({
getInitialState:function(){
return {result:0};
},
handlerClick: function () {
this.setState({result:this.refs.num1.value*this.refs.num2.value});
},
render: function () {
return (
<div>
<input type='number' ref='num1'/>
<input type='number' ref='num2'/>
<button onClick={this.handlerClick}>求乘数</button>
<p >{this.state.result}</p>
</div>
)
}
});
ReactDOM.render(<LianXi /> ,document.getElementById('example'));

  

25、react入门教程的更多相关文章

  1. react 入门教程 阮一峰老师真的是榜样

    -  转自阮一峰老师博客 React 入门实例教程   作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Nati ...

  2. React入门教程(二)

    前言 距离上次我写 React 入门教程已经快2个月了,年头年尾总是比较忙哈,在React 入门教程(一)我大概介绍了 React 的使用和一些注意事项,这次让我们来继续学习 React 一. Rea ...

  3. React入门教程1---初见面

    React入门教程1---初见面:https://blog.csdn.net/solar_lan/article/details/82799248 React 教程 React 是一个用于构建用户界面 ...

  4. 160921、React入门教程第一课--从零开始构建项目

    工欲善其事必先利其器,现在的node环境下,有太多好用的工具能够帮助我们更好的开发和维护管理项目. 我本人不建议什么功能都自己写,我比较喜欢代码复用.只要能找到npm包来实现的功能,坚决不自己敲代码. ...

  5. React 入门教程

    React 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内 ...

  6. React入门教程

    做前端的人都知道,目前热门前端的框架是 VAR => Vue,Anglur,React. 而如果说最热门的前端框架是谁,毫无悬念是 React React 是由 Facebook 主导开发的一个 ...

  7. 前端三大框架之一React入门教程

    相信大家对框架这个词都很熟悉吧,我一直喜欢js原生来开发,但是目前都要求工作效率,所有使用框架或者是库会使我们开发更加方便和快速,甚至一个人干十个人的活.. 框架优点: 1.方便开发.快速写功能 2. ...

  8. React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

  9. 2015年最热门前端框架React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...

随机推荐

  1. 【转】Android应用程序窗口(Activity)窗口对象(Window)创建指南

    在前文中,我们分析了Android应用程序窗口的运行上下文环境的创建过程.由此可知,每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一 ...

  2. 【洛谷P2607】[ZJOI2008]骑士

    骑士 题目链接 这道题一看,似乎和舞会是一样的,然而它并没有保证是一棵树 但是,对于每个连通块,必有相同的点数和边数,这样的图一定是一棵树上加一条边 这条边一定回使图中形成一个环,这种图貌似叫“基环树 ...

  3. 【题解】洛谷 P1525 关押罪犯

    题目 https://www.luogu.org/problemnew/show/P1525 思路 把所有边sort一遍从大到小排列 运用并查集思想敌人的敌人就是朋友 从最大边开始查找连着的两个罪犯 ...

  4. python tips(持续更新中)

    python tips 可变对象与不可变对象 在python中,可变对象有数值类型(int,float),字符串(str),元组(tuple),可变对象有列表(list),字典(dict),集合(se ...

  5. 框架篇 -- Struts2

    Struts框架很很早接触的一个框架知识,已经不那么频繁使用了,但是总结一下,复习一下还是很有必要的; Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MV ...

  6. java 后台返回文件流到浏览器

    package com.springbootblog.controller; import io.swagger.annotations.ApiImplicitParam;import io.swag ...

  7. onload函数不执行

    原因: <jsp:include page="">通过该标签引入jsp时会导致<body>失效 案例: <jsp:include page=" ...

  8. eclipse的中文插件链接及使用方法

    链接:http://www.eclipse.org/babel/downloads.php 帮助-->安装-->打开链接使用链接里面的语言包下载地址-->下载安装-->完成

  9. java HtmlEmail发送邮件工具类

    package com.sh.xrsite.common.utils; import java.io.File; import java.util.HashMap; import java.util. ...

  10. 青蛙的约会(exgcd/扩展欧几里得)

    题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清 ...