React项目实战

前言

近期我在负责开发一个大型电商平台项目,所采用的前端架构是React.js。设计到的技术栈有Reactjs、 React-Router、Redux、Nodejs、Webpack、Sass等等。这篇文章就以如今比较火的框架React.js来跟小伙伴们聊聊。css

就去年聊的水生火热的三大框架(React、vue、angular)。在这里我主要介绍的是Reactjs。分享给你们我近期开发的电商项目涉及到的知识点。若是你是准备近期着手学习Reactjs的,我能够推荐给你一些学习方法。若是你已经玩React易如反掌了,咱们能够一块儿聊聊React,聊聊JavaScript。若是你是React专家级别的,老司机请带带我。废话就很少说了。总之一句话,但愿小伙伴能共同窗习,共同进步。下面进入正题;html

原理

在Web开发中,咱们总须要将变化的数据实时反应到UI上,这时就须要对DOM进行操做。而复杂或频繁的DOM操做一般是性能瓶颈产生的缘由(如何进行高性能的复杂DOM操做一般是衡量一个前端开发人员技能的重要指标)。React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时全部的DOM构造都是经过虚拟DOM进行,每当数据变化时,React都会从新构建整个DOM树,而后React将当前整个DOM树和上一次的DOM树进行对比,获得DOM结构的区别,而后仅仅将须要变化的部分进行实际的浏览器DOM更新。前端

并且React可以批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,而后又从B变成A,React会认为UI不发生任何变化,而若是经过手动控制,这种逻辑一般是极其复杂的。尽管每一次都须要构造完整的虚拟DOM树,可是由于虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操做的仅仅是Diff部分,于是能达到提升性能的目的。这样,在保证性能的同时,开发者将再也不须要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只须要关心在任意一个数据状态下,整个界面是如何Render的。vue

若是你像在90年代那样写过服务器端Render的纯Web页面那么应该知道,服务器端所要作的就是根据数据Render出HTML送到浏览器端。若是这时由于用户的一个点击须要改变某个状态文字,那么也是经过刷新整个页面来完成的。服务器端并不须要知道是哪一小段HTML发生了变化,而只须要根据数据刷新整个页面。换句话说,任何UI的变化都是经过总体刷新来完成的。而React将这种开发模式以高性能的方式带到了前端,每作一点界面的更新,你均可以认为刷新了整个页面。至于如何进行局部更新以保证性能,则是React框架要完成的事情。node

借用Facebook介绍React的视频中聊天应用的例子,当一条新的消息过来时,传统开发的思路如上图,你的开发过程须要知道哪条数据过来了,如何将新的DOM结点添加到当前DOM树上;而基于React的开发思路以下图,你永远只须要关心数据总体,两次数据之间的UI如何变化,则彻底交给框架去作。能够看到,使用React大大下降了逻辑复杂性,意味着开发难度下降,可能产生Bug的机会也更少。react

React组件

组件属性:
git

ReactJS是基于组件化的开发,React 容许将代码封装成组件(component),而后像插入普通 HTML 标签同样,在网页中插入这个组件。算法

组件1redux

import React from 'react';

import CheckoutPurchasedHeader from '../../module/CheckoutPurchasedHeader' 

class OrderSkuList extends React.Component {
    constructor(props) {
        super(props); 
    }

    render(){
        let Header = ["商品信息","单价(元)","数量","小计(元)","操做"]
        return(
            <div className="order-detail-my-order">
                <CheckoutPurchasedHeader _Header={ Header } />
            </div>
        )
    }
}

export default OrderSkuList 
复制代码

组件2浏览器

import React, { Component, PropTypes } from 'react';
    class CheckoutPurchasedHeader extends Component {
        constructor(props){
            super( props);
        }
        render() {
            let { _Header } = this.props;
            let nodes = [];
            if( _Header ){
                nodes = _Header.map( (data,index)=>{
                    return <li key={ index }>{data}</li>
            })
        }

           return (
                <ul className="checkout-purchased-header">
                    { nodes }
                </ul>
            );
        }
    }

    export default CheckoutPurchasedHeader;
复制代码

看到这段代码,有几点须要注意:

  • 获取属性的值用的是this.props.属性名。

  • 建立的组件名称首字母必须大写。

  • 为元素添加css的class时,要用className。

  • 组件的style属性的设置方式也值得注意,要写成style={{width: this.state.witdh}}。

组件状态:

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

import React, { Component, PropTypes } from 'react';
    class CheckoutPurchasedHeader extends Component {
        constructor(props){
            super( props);
            this.state ={
                _Header: ["商品信息","单价(元)","数量","小计(元)","操做"]
            }
        }
        render() {
            let nodes = [];
            if( this.state._Header){
                nodes = this.state._Header.map( (data,index)=>{
                    return <li key={ index }>{data}</li>
            })
        }

           return (
                <ul className="checkout-purchased-header">
                    { nodes }
                </ul>
            );
        }
    }

    export default CheckoutPurchasedHeader;
复制代码

这里值得注意的几点以下:

  • this.state初始化该组件所要用到的对象。

  • 访问state的方法是this.state.属性名。

  • 变量用{}包裹,不须要再加双引号。

  • 能够经过this.setState方法来修改当前组件的state。当检测到state有变化的时候,组件会从新render.

组件的生命周期

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

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):组件判断是否从新渲染时调用。

组件的嵌套

React是基于组件化的开发,那么组件化开发最大的优势是什么?毫无疑问,固然是复用.仔细阅读上面第1点的代码,你会发现CheckoutPurchasedHeader组件能够在任何地方复用。

为何选择React?

React最初开发这个特别的框架目标是“搭建数据须要频繁更改的大型应用”。这也就能够说是React项目搭建算是蛮复杂的。好比说写一个简单的helloworld。其余的框架几行代码就解决,可是React写起来就比较繁琐。 但这也能够说是React的优势,代码的组件化,会大大的提高后期开发跟维护的效率。说到这里,我就要开始说说为何咱们要选择React.下面是我总结六点内容来阐述React的优点所在。

React效率极高
同构,纯粹的JavaScript
Javascript库(JSX)
一切都是component
单向数据流
Facebook

React的效率高只要体如今他的虚拟dom上

React.render(
<div className="commentBox">
  Hello, world! I am a CommentBox.
</div>  );
复制代码

这里的div其实和dom里面的div彻底是两码事儿,只不过React提供了和DOM相似的Tag和API,事实上React会经过他本身的逻辑去转化为真正的DOM。因此,把这种叫作虚拟DOM.

那么这样作有什么好处呢?最明显的一点好处就是React所谓的 dom diff ,可以实现delta级别的dom更新。当有数据变更致使DOM变更时,React不是全局刷新,而是经过它内部的 dom diff 算法计算出不一样点,而后以最小粒度进行更新。这也是React号称性能好的缘由。

其次,还有一点很是好的地方就在于,有了虚拟DOM就可让UI脱离设备,换句话说,只要有对应的转化关系,如:虚拟DOM -> 浏览器DOM,就能进行渲染。

React 使用 JSX 来替代常规的 JavaScript

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。它有如下优势:

JSX 执行更快,由于它在编译为 JavaScript 代码后进行了优化。

它是类型安全的,在编译过程当中就能发现错误。

使用 JSX 编写模板更加简单快速。

组件化

虚拟DOM(virtual-dom)不只带来了简单的UI开发逻辑,同时也带来了组件化开发的思想,所谓组件,即封装起来的具备独立功能的UI部件。React推荐以组件的方式去从新思考UI构成,将UI上每个功能相对独立的模块定义成组件,而后将小的组件经过组合或者嵌套的方式构成大的组件,最终完成总体UI的构建。例如,Facebook的instagram.com整站都采用了React来开发,整个页面就是一个大的组件,其中包含了嵌套的大量其它组件,你们有兴趣能够看下它背后的代码。若是说MVC的思想让你作到视图-数据-控制器的分离,那么组件化的思考方式则是带来了UI功能模块之间的分离。

React自己其实只是一个V,并非一个完整的框架

因此若是是大型应用想要一套完整的框架的话,react-router和redux是必不可少的。react的最大的问题就在于它组件跟组件之间的数据传递很麻烦,好比说父组件跟子组件公用同一个数据,子组件这时要修改数据的话,须要经过重重回调到父组件上,才能修改该数据,可是有了redux以后,全部的数据存放在顶层state树上,每一个组件均可以公用顶层数据源的数据。组件经过触发action来修改数据。

Facebook这条大腿支撑着React的开发迭代

在活跃度跟质量上天然是能够有保障的。上述这些优势也没法判定react就是一个很完美的框架,但最起码,它提出了一个全新的概念,新鲜的东西老是可以吸引你们的眼球。可是在架构选型上,得要根据实际应用的特色来选择合适的框架。

谈谈心得 最后一段我想阐述一些我实际开发中的心得。我作前端开发说长不长,说短也有四年了。所说的有不对的地方望指出。在过去的两年里前端这个市场忽然火起来了,致使一会儿出来了不少的前端开发人员。需求多了,竞争天然而然的也就多了。那么问题来了,咱们要怎样去突出本身?我发表几点我的意见。

不怕技术不成熟,关键是要用心。

不懂就问,要多沟通交流。不要让技术有局限性。

时常关注技术论坛。关注其余人写代码的方式,从中领悟优缺点。

时常要关注新的技术。

做者:@leotao

相关文章
相关标签/搜索