浅谈React与jQuery的思维差异

为什么越来越多的互联网公司都在转向React.js去开发前端组件,除了性能因素外,很大一部分原因是因为用jQuery去写很复杂的DOM操作,后期代码会变得越来越难维护。现在大部分的 Web APP 都有一个特点:后端的Model层很简单,但是随着产品业务的拓展前端View却变得越来越复杂,这个时候如果还在用纯jQuery去写DOM操作将会变得很不直观,代码也会变的很臃肿进而变的越来越难以维护,下面就拿一个微博发送框的简单例子来展示一些React的简洁与强大。


注意:

  • React并不适合所有项目,需要结合实际情况综合考虑

  • jQuery与React并不是一个层面上的东西,jQuery只是一个工具库,这里只是展示两种编程模式的思维差异

  • 理解一个技术的思想比学会怎么用它更重要,同时我们还需要知道不同的技术间的区别的核心在哪,这样我们才能学会用合适的技术去解决合适的问题

  • 这里的tweet box只是一个简化版的UI模型,仅用来说明jQuery和React的思维差异,并不具备发Twitter的功能

  • 你也可以写出简洁的jQuery代码。但是你必须想出良好的代码结构,每次想要增加新功能的时候还需要特别注意是否影响代码的重构,使用React会帮助你团队内部拥有更好的代码结构,页面性能也会得到相应的提高


需要实现的效果


  1. tweet box为空时,tweet button显示为灰色不可点击状态

  2. tweet box下方显示还可以输入的字符数量

  3. 点击add photo,剩余字符数量及add photo按钮状态发生改变(假定图片占用23个字符)


先来看看React版本:


React.js的提供了一整套Virtual DOM,所有的操作都在这个Virtual DOM上,只有当事件发生的时候,state才发生改变,之后,React自动调用render()来更新UI


下面是我托管在jsBin上的Demo:

React版本演示代码 

http://jsbin.com/verazi/5/edit?html,js,output


React代码处理问题的思路:


  1. 创建一个状态变量用来追踪textarea中的字符的数量

  2. 在textarea的onChange事件发生时改变其状态

  3. 使用render()重新渲染tweet box,显示还可以输入的字符的数量 


var TweetBox = React.createClass({

  getInitialState: function() {

    return {

      text: "",

      photoAdded: false

    };

  },

  handleChange: function(event) {

    this.setState({ text: event.target.value });

  },

  togglePhoto: function(event) {

    this.setState({ photoAdded: !this.state.photoAdded });

  },

  remainingCharacters: function() {

    if (this.state.photoAdded) {

      return 140 - 23 - this.state.text.length;

    } else {

      return 140 - this.state.text.length;

    }

  },

  render: function() {

    return (

        <div className="well clearfix">

            <textarea className="form-control" onChange={this.handleChange}></textarea>

            <br/>

            <span>{ this.remainingCharacters() }</span>

            <button className="btn btn-primary pull-right"

                    disabled={this.state.text.length === 0 && !this.state.photoAdded}>

                Tweet

            </button>

            <button className="btn btn-default pull-right" onClick={this.togglePhoto}>

                {this.state.photoAdded ? "✓ Photo Added" : "Add Photo" }

            </button>

        </div>

    );

  }

});


React.render(

  <TweetBox />,

  document.body

);


再来看看熟悉的jQuery版本


这里用到了Bootstrap框架,但是仅仅只是为了好看,如果不熟悉BootStrap的话请自动忽略CSS Class

因为jQuery只是一个工具库,它处理问题的思路是,用选择器选择DOM元素,有需要的话就对某个DOM元素进行监听,然后再事件监听函数里进行相对应的处理


jQuery版演示代码 

http://jsbin.com/geqisi/8/edit?html,js,output


jQuery处理问题的思路


  1. 给按钮或者文本框绑定监听事件

  2. 如果事件触发则开始判断,各个DOM对象的当前状态(通常会借助css class来表示状态)

  3. 改变对应的DOM来实现想要达到的效果(tweet box下方显示还可以输入的字符数量,按钮是否可点击)


<div class="well clearfix">

    <textarea class="form-control"></textarea><br>

    <span>140</span>

    <button class="js-tweet-button btn btn-primary pull-right" disabled>Tweet</button>

    <button class="js-add-photo-button btn btn-default pull-right">Add Photo</button>

</div>


// 给文本框绑定事件,监听是否有输入

$("textarea").on("input", function() {

    if ($(".js-add-photo-button").hasClass("is-on")) {

        // add phtot按钮已经点击,剩余输入文本数量再减23

        $("span").text(140 - 23 - $(this).val().length);

    } else {

        // 计算剩余文本数量

        $("span").text(140 - $(this).val().length);

    }


    if ($(this).val().length > 0 || $(".js-add-photo-button").hasClass("is-on")) {

            // 如果文本框里有内容或者add phtot按钮已经点击,tweet button设置为可点击状态

        $(".js-tweet-button").prop("disabled", false);

    } else {

            // tweet button设置为不可点击状态

        $(".js-tweet-button").prop("disabled", true);

    }

});


// 给添加照片的按钮绑定点击事件监听

$(".js-add-photo-button").on("click", function() {

    if ($(this).hasClass("is-on")) {

        $(this).removeClass("is-on").text("Add Photo");  

// 切换add photo按钮显示状态


        $("span").text(140 - $("textarea").val().length);

        if ($("textarea").val().length === 0) {

            // 切换tweet按钮前需要先判断textarea当前状态

            $(".js-tweet-button").prop("disabled", true);

        }

    } else {

        $(this).addClass("is-on").text("✓ Photo Added");  

// 切换add photo按钮显示状态


        $("span").text(140 - 23 - $("textarea").val().length);

        $(".js-tweet-button").prop("disabled", false);

    }

});


总结



在React中,只有当事件发生的时候,state才发生改变,之后,React自动调用render()来更新UI

state成为了事件以及render()之间过渡:

  1. 每个事件不需要担心哪一部分的DOM发生变化,他们只需要设置state就可以了

  2. 相应的,当你写render()的时候,你也只需要担心现在的state是什么

  3. jQuery没有中间的过渡层'state',我们需要花费很大的精力来解决它们之间相互的联系(对于复杂的组件,建议使用React而不是jQuery)

  4. React中把各个UI组件独立出来,有利于提高UI组件的复用率同时降低各个UI组件的耦合

  5. 新手在直接操作DOM时很难写出高效而又优雅的代码,从而使得前端代码满满变得越来越难以维护


也就是说,React适合用在那些DOM操作复杂的单页面应用,有利于提高代码可读性以及提高页面性能(可以参考React Diff算法);

jQuery则是个用来帮你完成一些基本操作的工具库


本文原文(不定期持续更新):

http://xunli.xyz/2016/01/16/react-vs-jquery/

如果需要阅读完整的教程,请阅读英文原文

http://reactfordesigners.com/labs/reactjs-introduction-for-people-who-know-just-enough-jquery-to-get-by/?utm_source=javascriptweekly&utm_medium=email

英文原文的中文翻译版(墨白):

http://segmentfault.com/a/1190000003501752?_ea=575445

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值