UDN-企业互联网技术人气社区

板块导航

浏览  : 1254
回复  : 0

[资源] 秒懂ReactJS

[复制链接]
我爱吃咸菜的头像 楼主
发表于 2016-5-10 07:14:34 | 显示全部楼层 |阅读模式
  来源:贾朝阳 ThoughtWorks

  这篇文章是为ReactJs小白准备的,希望他们快速抓住ReactJs的要点并能在实践中随机应变。

  两句话版本
  
  • ReactJs把视图更新简化为一个render函数
  • render函数接收两个参数,分别是配置项和状态

  长版本

  ReactJs是一个专注于View的Web前端框架。Web前端的View就是浏览器中的Dom元素,改变View的唯一途径就是修改浏览器中的Dom元素,因此ReactJs的核心任务就是如何修改Dom元素,作为一个成功的框架,ReactJs使修改Dom元素变得高效而又简单。

  ReactJs把修改Dom的操作简化成一个函数renderInto(parentDom, props, states)=>htmlString,这个函数的意图就是根据props,states计算出视图对应的html字符串并添加为parentDom的子节点。props和states就是普通的JavaScript对象,这个函数的核心逻辑就是计算html元素的机构及元素属性然后拼接成字符串返回。作为框架,ReactJs用JSX形式的DSL解决了拼接html的任务并接管了更新到parentDom的职责。看一个例子,理解这个函数并理解ReactJs怎么使用这个函数你就可以一个人开始ReactJs之旅了。
  
  1. var props = {name: 'myname'};  

  2.   var states = {amount: 1000};  

  3.   function render(props, states) {  

  4.     var title = ’Hello, ' + props.name;  

  5.     var description = 'You have ' + states.amount + ' score now.';  

  6.     return (  

  7.       <div className="score-board">  

  8.          <h1>{title}</h1>  

  9.          <p>{description}</p>  

  10.       </div>  

  11.     );  

  12.   }
复制代码

  函数第一行根据props计算title,第二行根据states计算description,最后以JSX形式返回拼接好的html字符串。

  如果你用过AngularJs,EmberJs等类似的前端框架,你可能会觉得没什么了不起,不就是把模板和逻辑放到一起吗?是的,没错,但这不仅仅是组织形式上的改变,而是编程隐喻的转变—从复杂的MVC或MVVM模式到简单的render函数。还有一点不同是JSX最终编译成调用react-dom的JavaScript语句,而不是直接生成字符串。

  render函数还只是ReactJs这座冰山的一角,”React”会在render函数的输入变化时再次调用这个函数。再看一个例子。
 
  1.  var props = {name: 'myname'};  

  2.   var states = {amount: 1000};  

  3.   function handleClickAdd() {  

  4.     states = {amount: states.amount + 1};  

  5.   }  

  6.   function render(props, states) {  

  7.     var title = ’Hello, ' + props.name;  

  8.     var description = 'You have ' + states.amount + ' score now.';  

  9.     return (  

  10.       <div className="score-board">  

  11.          <h1>{title}</h1>  

  12.          <p>{description}</p>  

  13.          <button onClick={handleClickAdd}>+1</button>  

  14.       </div>  

  15.     );  

  16.   }
复制代码

  这个例子增加了一个“+1”按钮,当用户点击按钮时会修改states,ReactJs在states变化时的”React”就是再次调用render函数,然后用新输出更新浏览器的dom。

  可能你会问,props和states不就是Model吗?是的,可以理解成Model,但此Model非彼Model,props和states都是为View服务的而非和View平起平坐。

  可能你还会问,为啥不把props和states合并成一个对象?要回答这个问题,就涉及到复杂视图的场景。想想看,当视图内的元素不断增加时,代码上如何处理,还要在一个render函数里折腾吗?肯定不会。我猜你已经想到了,要把大问题拆小。ReactJs给出的解决方法就是把大视图拆成若干个小视图,每个视图都有自己的render函数,在JSX中可以直接使用视图标签。看一个例子。
  
  1. var Score = React.createClass({  

  2.     initialState: function() {  

  3.       return {amount: 1000};  

  4.     },  

  5.     function handleClickAdd() {  

  6.       this.setState({amount: this.states.amount + 1});  

  7.     }  

  8.     render: function() {  

  9.       var title = ’Hello, ' + this.props.name;  

  10.       var description = 'You have ' + this.states.amount + ' score now.';  

  11.       return (  

  12.         <div className="score-board">  

  13.            <h1>{title}</h1>  

  14.            <p>{description}</p>  

  15.            <button onClick={handleClickAdd}>+1</button>  

  16.         </div>  

  17.       );  

  18.     }  

  19.   });  

  20.   var ScoreList = React.createClass({  

  21.     render() {  

  22.       return (  

  23.         <ul className="score-list">  

  24.           <li><Score name="Tom" /></li>  

  25.           <li><Score name="Jerry" /></li>  

  26.         </ul>  

  27.       );  

  28.     }  

  29.   });  

  30.   ReactDOM.render(  

  31.     <ScoreList />,  

  32.     document.getElementById('content')  

  33.   );
复制代码

  这个例子中有两类View,分别是Score和ScoreList。ScoreList的render函数中使用Score标签并给出配置项name的值。详细看一下Score,ReactJs提供createClass方法定义视图,在render函数中通过this.props访问外部传入的配置项,通过this.states访问视图内部的状态。从意图上看,props外部传入视图的配置项,拥有者是父视图,视图内部只能读取配置项,states的拥有者是视图自身。

  区分props和states的结果就是,子视图没办法直接改变父视图,视图改变一定是自触发改变的视图开始向子视图传播。对上面的例子,当Tom的Score改变时,ScoreList其他部分一定不会改变,所以视图更新从Tom的Score视图开始就可以,这就保证了能更高效地计算视图变化,再加上VirtualDom的使用,使ReactJs的效率大大超过其他框架。

  当子视图需要改变父视图时,也一定是从父视图开始向下更新。假如上面的例子中ScoreList还有平均分的视图,当Tom的分数改变时,需要更新ScoreList中的平均分。这就需要Score视图在处理”+1”输入时把变化通知到ScoreList,做法时给Score增加配置项,ScoreList中定义更新平均分的函数并把函数作为配置项传给Score。当ScoreList更新时,因为Jerry的props和states都没变化,所以Jerry的Score视图不需要更新。

  这就是ReactJs的全部秘密了(不过Web前端本身是一个复杂系统,你还需要了解更多其他内容)。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部