2五、react入门教程

0. React介绍

0.1 什么是React?

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

 

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

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

0.2 FB为何推出React?

React 起源于 Facebook 的内部项目,由于该公司对市场上全部 JavaScript MVC 框架,都不满意,就决定本身写一套,用来架设 Instagram 的网站。作出来之后,发现这套东西很好用,就在2013年5月开源了。java

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

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

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

0.3 React历史

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

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

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

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

 

 

六、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 等

 

 

 

七、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.1 生命周期的状态

Mounting 已经插入真是DOM

Updating 正在被从新渲染

Unmounting 已经移出DOM

8.2 状态的处理函数

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

一、  will 函数在进入状态以前调用

二、  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'));

  

 

九、使用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'));
相关文章
相关标签/搜索