HTML5技术

React 仅仅只是你的界限 - 一像素

字号+ 作者:H5之家 来源:H5之家 2016-03-10 12:34 我要评论( )

React 起源于Facebook内部项目,是一个用来构建用户界面的javascript库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内部通过state来维护组件状态的变化,当组件的状态发生变化时,React通过虚拟DOM技术

考虑到有的同学还不曾了解过React,我们先来写一个简单的React组件,让大家一睹为快!

复制代码
// 创建一个HelloReact组件
var HelloReact = React.createClass({
    render:function(){
        return (
            <div>
                 Hello React!
            </div>
        )
    }
});

// 使用HelloReact组件
ReactDOM.render(
    <HelloReact />,
    document.querySelector('body')
)
复制代码

这样就定义了一个React组件,当然要运行这段代码是有条件的,需要引入React库,还需要引入JSX语法转换库,这里不多说了,这些基础的东西还需要各位亲自实践才好!

 

React 核心技术 —— 虚拟DOM(Virtual DOM)


在前端开发的过程中,我们经常会做的一件事就是将变化的数据实时更新到UI上,这时就需要对DOM进行更新和重新渲染,而频繁的DOM操作通常是性能瓶颈产生的原因之一,有时候我们会遇到这样一种尴尬的情况:比如有一个列表数据,当用户执行刷新操作时,Ajax会重新从后台请求数据,即使新请求的数据和上次完全相同,DOM也会被全部更新一遍并进行重新渲染,这样就产生了不必要的性能开销。

React为此引入了虚拟DOM(Virtual DOM)机制:对于每一个组件,React会在内存中构建一个相对应的DOM树,基于React开发时所有的DOM构造都是通过虚拟DOM进行,每当组件的状态发生变化时,React都会重新构建整个DOM数据,然后将当前的整个DOM树和上一次的DOM树进行对比,得出DOM结构变化的部分(Patchs),然后将这些Patchs 再更新到真实DOM中。整个过程都是在内存中进行,因此是非常高效的。借用一张图可以清晰的表示虚拟DOM的工作机制:

 

React 的生命周期


React 把每个组件都当作一个状态机来维护和管理,因此每个组件都拥有一套完整的生命周期,大致可以分为三个过程:初始化、更新和销毁。生命周期的每一个过程都明确的反映了组件的状态变化。对于开发来说就能很容易的把握组件的每个状态,不同的状态时期做对应的事情,互不干扰。以下是和组件生命周期相关的几个方法:

getDefaultProps —— 组件创建时

getInitialState —— 组件实例化状态

componentWillMount —— 组件挂载前

componentDidMount —— 组件挂载后

componentWillReceiveProps —— 组件属性被改变时

shouldComponentUpdate —— 组件是否更新

componentWillUpdate —— 组件更新前

componentDidUpdate —— 组件更新后

componentWillUnmount —— 组件销毁前

 

初始化


对于外部系统来说,组件是一个独立存在的封闭系统,内部的逻辑被隐藏,只对外暴露传递数据的接口,而React为我们提供了两种方式来向组件传递数据,即 props 和 state。

props 是在调用ReactDOM.render() 时通过标签属性xxx传递,然后通过 this.props.xxx 来获取,getDefaultProps允许你为组件设置一个默认的props值,在没有传递props的情况下显示默认值。

复制代码
// 创建HelloReact组件
var HelloReact = React.createClass({
    /**
     * 当设置props的默认值 当没有传递时显示默认值
     * @return {}
     */
    getDefaultProps:function(){
       return {
           data:"暂无数据"
       }
    },
    render:function(){
        return (
            <div>
               //显示data,当props发生变化时会自动更新
               {this.props.data}
            </div>
        )
    }
});//传递props属性data
ReactDOM.render(
   <HelloReact data={"Hello React!"} />,
   document.querySelector('body')
)
复制代码

和 props 不同的是,state不能通过外部传递,因此在使用state之前,需要在getInitialState中为state设置一个默认值,然后才能通过this.state.xxx来访问,当组件被挂载完成时,触发componentDidMount方法,我们可以在这里通过Ajax请求服务器数据,然后再通过setState()把state的值设置为真实数据。

复制代码
// 创建HelloReact组件
var HelloReact = React.createClass({
    /**
     * 设置组件的初始值
     * @returns {{data: Array, msg: string}}
     */
    getInitialState:function(){
        return {
            data:"数据加载中..." //初始值为[]
        }
    },
    /**
     * 挂载后首次加载数据
     */
    componentDidMount:function(){
        this.requestData();//请求数据
    },
    /**
     * 请求后台数据
     */
    requestData:function(){
        $.ajax({
            url:'xxxx.ashx',
            data:{},
            success:function(data){
                this.setState({
                    data:data  //通过setState()更新服务器数据
                })
            }
        }.bind(this))
    },
    render:function(){
        return (
            <div>
               {this.state.data}
            </div>
        )
    }
});
ReactDOM.render(
    <HelloReact  />,
    document.querySelector('body')
)
复制代码

 

更新


props属性是只读的,如果想要改变props的值,只能通过重新调用render()来传递新的props,但要注意的是,重新执行render()组件不会被重新挂载,而是通过虚拟DOM技术进行增量更新和渲染,这时还会触发componentWillReceiveProps方法,并将新的props作为参数传递,你可以在这里对新的props进行处理。

相比props,state天生就是用来反映组件状态的,因此它的值是可以被改变的,当state的值被改变时,通过setState就可以改变state的值,React同样也是采用虚拟DOM技术来计算需要被更新的部分,而不是牵一发动全身的更新和渲染。

当props和state的状态发生变化后,组件在即将更新之前还会触发一个叫shouldConponentUpdate的方法,如果shouldConponentUpdate返回的是true,不管props和state的值和上一次相比有没有变化,React都会老老实实的进行对比。此时,如果你确定以及肯定两次数据没有变化,那就让shouldConponentUpdate返回false,React就不会进行diff了,更不会重新渲染了。瞬间省去了diff的时间,是不是很机智的说。

 

销毁


当组件从DOM中被移除时,React会销毁之。在销毁之前,细心的React还触发componentWillUnmount来通知你,看你最后有没有什么话想对这个即将逝去的组件说,当然你没什么事就不用了。

 

什么时候用props,什么时候用state


我们已经知道可以通过props和state两种方式向组件传递数据,props是只读的不能被改变,而state是用来反映一个组件的状态,是可以改变的。因此,当组件所需要的数据在调用时是已经确定的,不频繁发生变化的,就可以使用props来传递,相反,当组件所需要的数据在调用时不能确定,需要等待异步回调时才能确定,比如ajax请求数据,input的onchange事件,这时就需要使用state来记录和改变这些值得变化。

 

React 给前端带来的反思


以上便是对React的一个简单认识,React到底有多好?  我们需要反思,在WebApp横行霸道的时代,各路优秀的JS库百花齐放,旨在解决移动端的性能问题和开发效率。对于一个前端开发人员来说,既要跟上时代的步伐,也不能被这些新事物迷失了方向,每当一个新的事物被推出来之前,一定有一个强大的力量在背后做足了品牌包装。因此,对于我们来说既不能盲目崇拜,也不能消极对待,取其精华,去其糟粕,在取与舍之间找到一个平衡,来开阔自己的眼界,因为React仅仅只是你的界限。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖湾

    【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖

    2017-04-16 18:00

  • 【react框架】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的

    【react框架】利用shouldComponentUpdate钩子函数优化react性能以及

    2017-04-16 09:02

  • 前端开发框架简介:angular和react - 腾讯云技术社区

    前端开发框架简介:angular和react - 腾讯云技术社区

    2017-04-11 18:02

  • 不仅仅是写代码,而是完成作品 - mindwind

    不仅仅是写代码,而是完成作品 - mindwind

    2017-04-06 14:00

网友点评