React(9)-React周边类库

学习Reac很简单,然而随着学习的深入,才发现React强大的地方不仅仅是它的简单以及性能好,而是庞大的周边类库,学习React,它不是一个库,也不是一个框架,而是一个庞大的体系。想要发挥它的威力,整个技术栈都要配合它改造。你要学习一整套解决方案,从后端到前端,都是全新的做法。

Flux,React-Redux,React-Router,React-Native等等一系列的周边。我也会在随后,利用工作之余不断更新关于这些类库和React-Native(手机APP开发新的模式)的博客。

1.Jest

Jest是FaceBook开发的一个测试工具,它基于Jasmine测试框架提供相近的方式,使用expect(value).tobe(other)断言。需要配置nodeJS环境。注意:目前win下不能使用jest测试。

常见的测试类型:

单元测试的目的是保证函数或者模块完成我们想要的功能。

集成测试的目的是保证整个系统是否正常。

回归测试的目的确保改动没有破坏系统。

冒烟测试的目的是快速发现问题。

压力测试的目的是确定系统性能。

1.安装,npm install jest-cli

2. 测试目标文件sum.js

function sum(a,b){
  return a+b;
}
module.exprots = sum;

3.编写测试文件sum-test.js

jest.dontMock('../sum');
destcribe('sum',function(){
  it('add 1+2 to equal 3',function(){
     var sum = require('../sum');
     expect(sum(1,2)).toBe(3);
  })
})
4.命令行输入jest sum-test

2.Immutable.js

immutableJs是Fb开发的一个JS库,能够在JS中实现不可变对象。不可变对象大大提高了对象比较性能,用于状态和属性判断非常有效,实际上,提高比较性能的代价是降低修改性能,只不过收益更大。

不可变数据结构中的数据是不允许修改的,相反,如果需要修改,它们会返回原始数据的一个经过修改的拷贝。

首先先看一个不使用Immutable的React组件:

<script src="../JS/react-0.14.7/build/react-with-addons.js" type="text/javascript" charset="utf-8"></script>
<script src="../JS/react-0.14.7/build/react-dom.js" type="text/javascript" charset="utf-8"></script>
<script src="../JS/immutable/dist/immutable.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<div id="app"></div>
<script type="text/babel">
      var CheckBox = React.createClass({
          onChange:function(){
              this.props.onChange(this.props.label.id)
          },
          //我试着在这里放shouldComponentUpdate,结果组件不能运行。
          render:function(){
              return (
                <label>
                    {this.props.label.text}
                    <input type="checkbox" 
                        checked={this.props.label.checked}
                        onChange={this.onChange}
                    />
                    {this.props.label.checked ? this.props.label.on : this.props.label.off}     
                </label>
              )
          }
      });
      var Demo = React.createClass({
          mixins:[React.addons.PureRenderMixin],
        getInitialState: function() {
          return {
              items: [
                 {
                     id:0,
                     text:"LoL",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 },
                 {
                     id:1,
                     text:"WaW",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 },
                 {
                     id:2,
                     text:"Dota2",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 }
              ]
          };
        },
        onChange:function(ID){
            var NewState = this.state.items.concat([]);
            NewState[ID].checked = !NewState[ID].checked;
            this.setState({
                items:NewState
            })
        }, 
        render: function() {
          var that = this;
          return (
           <div>
                {
                    this.state.items.map(function(item){
                        return <div key={"id"+item.id}><CheckBox label={item} onChange={that.onChange}/></div>
                    })
                }
           </div>
          );
        }
      });
      ReactDOM.render(
        <Demo />,
        document.getElementById('app')
      );
      window.Perf = React.addons.Perf;
      //Perf.start()
      //Perf.stop()
      //Perf.printInclusive()
</script>

然后先输入Perf.start()开始监听,点击复选框,Perf.stop()停止监听,在输入Perf.printInclusive()就可以看出性能的消耗。接着再看使用Immutable的React组件:

<div id="app2"></div>
<script type="text/babel">
      var CheckBoxWithLabel = React.createClass({
          onChange:function(){
              this.props.onChange(this.props.label.get("id"))
          },
          shouldComponentUpdate:function(nextProps,nextState){
            return nextProps.label != this.props.label;
        },
          render:function(){
              return (
                <label>
                    {this.props.label.get("text")}
                    <input type="checkbox" 
                        checked={this.props.label.get("checked")}
                        onChange={this.onChange}
                    />
                    {this.props.label.get("checked") ? this.props.label.get("on") : this.props.label.get("off")}     
                </label>
              )
          }
      });
      var ImmutableDemo = React.createClass({
          mixins:[React.addons.PureRenderMixin],
        getInitialState: function() {
          return Immutable.fromJS({
              items: [
                 {
                     id:0,
                     text:"亚索",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 },
                 {
                     id:1,
                     text:"劫",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 },
                 {
                     id:2,
                     text:"菲兹",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 },
                 {
                     id:3,
                     text:"瑞文",
                     on:"喜欢",
                     off:"不喜欢",
                     checked:false
                 }
              ]
          });
        },
        onChange:function(ID){
            var NewState = this.state.setIn(["items",ID,"checked"],!this.state.getIn(["items",ID,"checked"]));
            this.replaceState(NewState)
        }, 
        render: function() {
          var that = this;
          return (
           <div>
                {
                    this.state.get("items").map(function(item){
                        return <div key={"item"+item.get("id")}><CheckBoxWithLabel label={item} onChange={that.onChange}/></div>
                    })
                }
           </div>
          );
        }
      });
      ReactDOM.render(
        <ImmutableDemo />,
        document.getElementById('app2')
      );
      window.Perf = React.addons.Perf;
      //Perf.start()
      //Perf.stop()
      //Perf.printInclusive()
</script>

同样的方法,就可以看出使用Immutable的组件每次更新被点击的复选框状态,而不是像没有使用的Immutable的组件,点击之后更新整个父组件的状态。
Immutable