您的位置:新葡亰496net > 新葡亰官网 > 新葡亰496netjs深入学习详细解析,js实现原生js拖

新葡亰496netjs深入学习详细解析,js实现原生js拖

发布时间:2019-11-05 00:40编辑:新葡亰官网浏览(50)

    React.js实现原生js拖拽效果及思考

    2016/07/16 · JavaScript · ReactJS

    本文作者: 伯乐在线 - winty 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    一、起因&思路

    不知不觉,已经好几天没写博客了。。。近来除了研究React,还做了公司官网。。。

    一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨。所以就用react来实现这个拖拽效果。

    首先,其实拖拽效果的思路是很简单的。主要就是三个步骤:

    1.onmousedown的时候,启动可拖拽事件,记录被拖拽元素的原始坐标参数。

    2.onmousemove的时候,实时记录鼠标移动的距离,结合被拖拽元素第一阶段的坐标参数,计算并设置新的坐标值。

    3.onmouseup的时候,关闭可拖拽事件,记录新的坐标值。

    注意:这里主要是通过绝对定位的top和left来确定元素的位置的,因此被拖拽元素的css一定要设置绝对定位。

    二、辅助工具

    辅助工具主要就是是开发过程变得高效,而且酷炫的。在这个demo中,要给大家推荐一个gulp browser-sync的开发工具,gulp有很多功能,在这个demo中gulp的作用主要是可以设置实时编译react中的jsx文件,当然如果你写css用的是sass,也可以设置实时编译sass。用browser-sync这个呢,主要就是可以自动实时刷新页面,我们平时做页面,看效果的时候,通常都是通过F5来刷新浏览器,然后看到页面的。但是用了这个插件,你写完代码的时候,只要按下,ctrl s保存,新的效果就会自动在浏览器中刷新,然后看得到了。

    用法详解:

    安装:

    1.在node的环境下,安装gulp,这里就不详说了,具体过程可参考我的博文《react.js入门必须知道的那些事》

    2.安装gulp-livereload,在命令行或者git bash ,输入npm install –save-dev gulp-livereload

    3.安装gulp-watch,在命令行或者git bash ,输入npm install –save-dev gulp-watch

    4.安装browser-sync,在命令行或者git bash ,输入npm install –save-dev browser-sync

    配置及解释如图:

    新葡亰496net 1

    三、定义组件构建页面

    备注:这里的代码说明均在react相关模块安装好的情况下,安装过程见我的博文《react.js入门必须知道的那些事》.

    效果图:

    新葡亰496net 2

    组件拆分思路:

    我当时觉得组件拆分得细一点好,所以我把input、button分别做成了一个组件:

    JavaScript

    var React=require('react'); var MyInput=React.createClass({ render:function(){ return ( <div className="form-group"> <label htmlFor={this.props.labelId} className="col-sm-2 control-label{this.props.labelTip</label> <div className="col-sm-10"> <input name={this.props.name} type={this.props.type} onChange={this.props.onChange} className="form-control" id={this.props.labelId} placeholder={this.props.placeholder}/> </div> </div> ); } }); module.exports=MyInput;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var React=require('react');
    var MyInput=React.createClass({
      render:function(){
        return (
        <div className="form-group">
            <label htmlFor={this.props.labelId} className="col-sm-2 control-label{this.props.labelTip</label>
            <div className="col-sm-10">
                 <input name={this.props.name} type={this.props.type} onChange={this.props.onChange} className="form-control" id={this.props.labelId} placeholder={this.props.placeholder}/>
            </div>
        </div>
      );
      }
    });
     
    module.exports=MyInput;

    JavaScript

    var React=require('react'); var Button=React.createClass({ render:function(){ return ( <button type={this.props.type} className="loginButton">{this.props.ButtonTip}</button> ); } }) module.exports=Button;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var React=require('react');
    var Button=React.createClass({
        render:function(){
            return (
                <button type={this.props.type} className="loginButton">{this.props.ButtonTip}</button>
            );
        }
    })
    module.exports=Button;

    由于input有很多都是需要指定的,这种情况下,如果像我这样定义需要传太多参数,而且其实登陆的input大多都是固定且没必要复用的,所以这样其实不大好。这里的input直接写比较好。

    写好之后的父组件:

    JavaScript

    render:function(){ return ( <form className="form-horizontal" id="form" ref="dragBox" onSubmit={this.submitHandler} onMouseMove={this.move} onMouseUp={this.endDrag}> <DragArea callbackParent={this.onChildChanged} /> <div id="form-wrap"> <MyInput name="username" labelId={"userId"} labelTip={"用户名"} type={"text"} placeholder={"请输入用户名"} value={this.state.username} onChange={this.handleChange}/> <MyInput name="password" labelId={"pw"} labelTip={"密码"} type={"password"} placeholder={"请输入密码"} value={this.state.password} onChange={this.handleChange}/> <div className="form-group"> <div className="col-sm-offset-2 col-sm-10"> <div className="checkbox"> <label> <input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange} /> 记住我 </label> </div> </div> </div> <MyButton type={"submit"} ButtonTip={"登陆"}/> </div> </form> );

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    render:function(){
       return (
        <form className="form-horizontal" id="form"  ref="dragBox" onSubmit={this.submitHandler} onMouseMove={this.move} onMouseUp={this.endDrag}>
        <DragArea callbackParent={this.onChildChanged} />
        <div id="form-wrap">
        <MyInput name="username" labelId={"userId"} labelTip={"用户名"} type={"text"} placeholder={"请输入用户名"} value={this.state.username} onChange={this.handleChange}/>
        <MyInput name="password" labelId={"pw"} labelTip={"密码"} type={"password"} placeholder={"请输入密码"} value={this.state.password} onChange={this.handleChange}/>
        <div className="form-group">
        <div className="col-sm-offset-2 col-sm-10">
        <div className="checkbox">
        <label>
        <input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange} /> 记住我
        </label>
        </div>
        </div>
        </div>  
        <MyButton type={"submit"} ButtonTip={"登陆"}/>
        </div>
        </form>
        );

    备注:因为demo中需要获取真实的dom节点,所以定义了ref。

    再加上css样式,页面就完成啦!最后,重点来啦!!!

    四、父子组件间通信实现拖拽

    说明:由于我要实现的效果是,鼠标按住子组件DragArea的时候,拖动的是整个form,所以启动拖拽的是DragArea,而响应的是form。所以,一开始必须把父组件的一些状态属性传给子组件,然后鼠标在DragArea按下的的时候,必须通过子组件DragArea找到父组件的原始坐标参数,然后更新父组件里面的状态属性,并且告诉父组件可以进行拖拽了。父组件给子组件传参就是直接传递的。而子组件给父组件传参需要通过事件。所以在父组件中定义这么一个函数:

    JavaScript

    onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传 this.setState(newState); },

    1
    2
    3
    onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传
        this.setState(newState);
    },

    而子组件需要绑定这个函数,如上面的代码:callbackParent={this.onChildChanged}

    在子组件中,响应的函数为:

    JavaScript

    startDrag:function(e){ var dragBox=document.getElementById('form'); var newState={}; var event=e||window.event; event.preventDefault(); var computedStyle=document.defaultView.getComputedStyle(dragBox,null); newState.left=computedStyle.left; newState.top=computedStyle.top; newState.currentX=event.clientX; newState.currentY=event.clientY; newState.flag=true; <span style="color: #0000ff;"> this.props.callbackParent(newState);</span> }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    startDrag:function(e){
        var dragBox=document.getElementById('form');
            var newState={};
            var event=e||window.event;
            event.preventDefault();
            var computedStyle=document.defaultView.getComputedStyle(dragBox,null);
            newState.left=computedStyle.left;
            newState.top=computedStyle.top;
            newState.currentX=event.clientX;
            newState.currentY=event.clientY;
            newState.flag=true;
        <span style="color: #0000ff;">    this.props.callbackParent(newState);</span>
    }

    这样,在子组件中就启动了拖拽开关,并且已经更新了from的相关参数,from的两外两个事件,move和endDrag分别为:

    JavaScript

    move:function(event){ var e = event ? event : window.event; //兼容IE的写法 if (this.state.flag) { var nowX = e.clientX, nowY = e.clientY; var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY; ReactDOM.findDOMNode(this.refs.dragBox).style.left = parseInt(this.state.left) disX "px"; ReactDOM.findDOMNode(this.refs.dragBox).style.top = parseInt(this.state.top) disY "px"; } }, endDrag:function(){ var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null); this.setState({ left:computedStyle.left, top:computedStyle.top, flag:false }); }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    move:function(event){
        var e = event ? event : window.event;  //兼容IE的写法
        if (this.state.flag) {
            var nowX = e.clientX, nowY = e.clientY;
            var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY;
            ReactDOM.findDOMNode(this.refs.dragBox).style.left = parseInt(this.state.left) disX "px";
            ReactDOM.findDOMNode(this.refs.dragBox).style.top = parseInt(this.state.top) disY "px";
        }
    },
    endDrag:function(){
        var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null);
        this.setState({
            left:computedStyle.left,
            top:computedStyle.top,
            flag:false
        });
    }

    至此,拖拽实现!

    五、反思回顾

    1.理论上来说,拖拽效果可以在任意元素中实现,拖拽的思路都是一致的,所以理论上来说,拖拽各个过程的函数可以抽离出来,做成一个Mixin,然后可以反复调用。我一开始的思路就是这样,但是在传参、响应、绑定元素上面总是出错。查找了一下资料,没找到react与拖拽的简单写法资料,只有一些react的专用插件,而且是用ES6的写法,由于现在的水平还没能看懂。所以暂时放弃了这种写法。希望有相关想法的大神们和我交流一下。

    2.文中子组件获取from的参数时,用了var dragBox=document.getElementById(‘form’);去找dom,这样好像违反了react的一些理念。但是我还不是很熟悉该怎么从子组件获取父组件的dom。我试过在父组件定义refs=this.refs.dragBox。然后传给子组件,但是不知道为什么浏览器一直报错说这个不是dom节点。求大神指教。

    3.拖拽事件的一般写法,是在document上面定义mousemove和mouseup事件,但是这两个事件都关联到from的参数,这样的话,如果我在react中定义在document,就跟踪不了相关参数。所以我就定义在了from上面。是不是有更好的方法呢?求分享!

    4.革命尚未成功,同志仍需努力!

     

    本demo已上传至:

    备注:由于本demo比较简单,理解代码应该没有什么问题,所以没有写代码说明,请见谅!

    打赏支持我写出更多好文章,谢谢!

    打赏作者

    React.js深入学习详细解析

    2016/07/16 · JavaScript · ReactJS

    本文作者: 伯乐在线 - winty 。未经作者许可,禁止转载!
    欢迎加入伯乐在线 专栏作者。

    今天,继续深入学习react.js。

    目录:

    一、JSX介绍

    二、React组件生命周期详解

    三、属性、状态的含义和用法

    四、React中事件的用法

    五、组件的协同使用

    六、React中的双向绑定

     一、JSX介绍

    ①定义

    JSX=JavaScript XML,是一种在React组件内部构建标签的类XML语法。React在不使用JSX的情况下一样可以工作,但是使用JSX可以提高组件的可读性,增强JS语义,结构清晰,抽象程度高,代码模块化。因此推荐在React中使用JSX。

    ②特点

    1、元素名首字母大写

    2、符合嵌套规则

    3、可以写入求值表达式

    4、驼峰式命名

    5、不能使用javascript原生函数的一些关键词,如for和class。需要替换成htmlFor和className

    ③使用方法

    1、使用动态值:JSX将两个花括号之间的内容{…}渲染为动态值,花括号指明了一个javascript上下文环境,花括号里面可以是一个变量,也可以是函数。 例如:

    JavaScript

    var name=“winty”; <p>{name}</p>

    1
    2
    3
    var name=“winty”;
     
    <p>{name}</p>

    JavaScript

    function date(d){ return [ d.getFullYear(), d.getMonth() 1, d.getDate() ].join('-); }; <p>{date(new Date()}</p>

    1
    2
    3
    4
    5
    6
    7
    8
    function date(d){
      return [
        d.getFullYear(),
        d.getMonth() 1,
        d.getDate()
      ].join('-);
    };
    <p>{date(new Date()}</p>

    2.注释:首先,在子节点中注释要用大括号包裹起来,然后就可以单行注释/**/,也可以多行注释//。

    JavaScript

    var Hello=React.createClass({ render:function(){ return <p name="winty"> //set name Hello ,World /* 多行注释 多行注释 */ </p> } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var Hello=React.createClass({
         render:function(){
             return <p name="winty"> //set name
                      Hello ,World
                      /*
                        多行注释
                        多行注释
                      */
                      </p>
               }
       });

    3.使用CSS内联样式

    JavaScript

    var style={ color:#000; }; React.render(<div style={style}>....</div>,document.body);

    1
    2
    3
    4
    var style={
        color:#000;
    };
    React.render(<div style={style}>....</div>,document.body);

    4.使用条件判断

    JavaScript

    //方法1,三目运算符 var Hello=React.createClass({ render:function(){ return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p> } }); //方法2,if-else语句 var Hello1=React.createClass({ getName:function(){ if(this.props.name) return this.props.name; else return "LuckyWinty"; render:function(){ return <p>Hello,{this.getName}</p> } }); //方法3,使用逻辑||运算符 var Hello3=React.createClass({ render:function(){ return <p>Hello,{this.props.name||"LuckyWinty"}</p> } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //方法1,三目运算符
    var Hello=React.createClass({
         render:function(){
            return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p>
         }
    });
     
    //方法2,if-else语句
    var Hello1=React.createClass({
         getName:function(){
              if(this.props.name)
                return this.props.name;
              else
                return "LuckyWinty";
         render:function(){
            return <p>Hello,{this.getName}</p>
         }
    });
    //方法3,使用逻辑||运算符
    var Hello3=React.createClass({
         render:function(){
            return <p>Hello,{this.props.name||"LuckyWinty"}</p>
         }
    });

    ④非DOM属性介绍

    JSX中有3个非DOM属性,分别是:dangerouslySetInnerHTML、ref、key。

    dangerouslySetInnerHTML:在JSX中直接插入HTML代码,但是如果能避免使用这个属性则尽量避免使用。

    不合时宜的使用 innerHTML 可能会导致 cross-site scripting (XSS) 攻击。 净化用户的输入来显示的时候,经常会出现错误,不合适的净化也是导致网页攻击 的原因之一。

    在彻底的理解安全问题后果并正确地净化数据之后,生成只包含唯一 key __html 的对象,并且对象的值是净化后的数据。例如:

    JavaScript

    function createMarkup() { return {__html: 'First · Second'}; }; <div dangerouslySetInnerHTML={createMarkup()} />

    1
    2
    3
    4
    function createMarkup() {
      return {__html: 'First &middot; Second'};
    };
    <div dangerouslySetInnerHTML={createMarkup()} />

    ref:父组件引用子组件,你可以通过在属性中设置期望的引用名来定义一个引用。例如:

    JavaScript

    ... render:function(){ return <div> <input ref="MyInput" .../> </div> } ... //然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了

    1
    2
    3
    4
    5
    6
    7
    8
    ...
    render:function(){
      return <div>
               <input ref="MyInput" .../>
               </div>
    }
    ...
    //然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了

    key:是一个可选的唯一标识符,通过给组件设置一个独一无二的键,并确保它在一个渲染周期中保持一致,使得React能够更只能地决定应该重用一个组件还是销毁并重建一个组件,进而提高渲染性能。例如:

    JavaScript

    var Hello3=React.createClass({ render:function(){ return <ul> <li key="1">1</li> <li key="2">2</li> <li key="3">3</li> </ul> } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var Hello3=React.createClass({
         render:function(){
            return <ul>
                    <li key="1">1</li>
                    <li key="2">2</li>
                    <li key="3">3</li>
             </ul>
         }
    });

    更多详细信息请参考:

     

    二、React组件生命周期详解

    组件本质上就是状态机,输入确定,输出一定确定。状态和结果一一对应,从而使程序变得直观。状态发生转换时会触发不同的钩子函数,从而让开发者有机会做出响应。可以用事件的思路来理解状态,但是事件与事件之间互相独立,但是不同状态之间可能会互相影响。

    组件的所有状态结合起来就成了组件的生命周期。即:初始化阶段->运行中阶段->销毁阶段。

    不同生命周期内可以自定义的函数

    初始化阶段:

    ①getDefaultProps:获取默认属性,只调用一次,是在createClass之后调用的。实例之间共享引用

    ②getInitialState:初始化每个实例的特有初始化状态

    ③componentWillMount:mout就是装载的意思,这个方法的意思就是说组件即将被装载到页面中,也是render之前最后一次修改状态的机会

    ④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上。只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。

    ⑤componentDidMount:组件被装载后才会被调用,也就是说调用这个方法的时候,组件已经被渲染到了页面上,这个时候可以修改DOM

    这五个函数的执行顺序就是从上到下的。需要注意的是getDefaultProps只会在组件的第一个实例被初始化的时候被调用,也就是说第二个实例之后都是从getInitialState开始调用。同一个组件的所有实例的默认属性都是一样的。

    主要测试代码:

    JavaScript

    <script type="text/babel"> var Hello=React.createClass({ getDefaultProps:function(){ console.log("getDefaultProps, 1"); }, getInitialState:function(){ console.log("getInitialState, 2"); return null; }, componentWillMount:function(){ console.log("componentWillMount, 3"); }, render:function(){ console.log("render, 4"); return <p>Hi,LuckyWinty!</p> }, componentDidMount:function(){ console.log("componentDidMount, 5"); }, }); React.render(<Hello></Hello>,document.body); </script>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <script type="text/babel">
        var Hello=React.createClass({
          getDefaultProps:function(){
              console.log("getDefaultProps, 1");
          },
          getInitialState:function(){
              console.log("getInitialState, 2");
              return null;
          },
          componentWillMount:function(){
              console.log("componentWillMount, 3");
          },
          render:function(){
              console.log("render, 4");
              return <p>Hi,LuckyWinty!</p>
          },
          componentDidMount:function(){
              console.log("componentDidMount, 5");
          },
        });
        React.render(<Hello></Hello>,document.body);
    </script>

    运行结果:

    新葡亰496net 3

    运行中阶段:

    ①componentWillReceiveProps:这个函数在组件即将接收到属性时触发的,或者是父组件的属性发生变化时,属性在传送到组件之前,开发者有机会通过这个函数去处理属性。比如修改,更新内部状态等。

    ②shouldComponentUpdate:当组件接收到新属性或者新状态的时候触发的。这个是一个疑问函数,也就是说我们可以告诉react不去更新某个组件。因为有时候属性或者状态并不会导致组件发生更新。在组件不需要更新的情况下,手动使shouldComponentUpdate返回false,这样react就不需要再经过render和diff算法去判断是否要更新,从而提高性能。

    ③componentWillUpdate:render触发之前触发,更新组件,不能修改属性和状态

    ④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上,只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。

    ⑤componentDidUpdate:render之后,真正的DOM被渲染之后调用

    备注:这五个函数的执行顺序也是从上到下的。这个的测试代码已上传至:

    销毁阶段:

    ①componentWillUnmount:这个函数在销毁操作真正执行之前调用,给开发者最后的机会进行一些清理工作。

    三、属性、状态的含义和用法

    属性的含义:

    props=properties,属性是不可以由组件自己进行修改的,组件的属性是由父组件传递进来的。

    属性的用法:

    一、键值对

    XHTML

    <Hello name="winty"/> 字符串 <Hello name={123}/> 大括号包裹的求值表达式 <Hello name={[1,2,3]}/> 传入数组 <Hello name={winty}/> 变量

    1
    2
    3
    4
    <Hello name="winty"/>   字符串
    <Hello name={123}/>    大括号包裹的求值表达式
    <Hello name={[1,2,3]}/>   传入数组
    <Hello name={winty}/>   变量

    二、展开定义(个人认为就是对象式定义)

    JavaScript

    var props={ one:"123", two:"22" }

    1
    2
    3
    4
    var props={
       one:"123",
       two:"22"
    }

    这样定义的话,理论上使用应该是one={props.one}这样调用,但是这样写起来比较繁琐,而且如果数据被修改,就需要对应修改相应的赋值,并且无法动态地设置属性,所以react中添加了一种展开语法:

    <Hello {…props}/>    //也就是三个点加上对象名称。

    这样使用展开语法,react就会自动把对象中的变量和值当作是属性的赋值,所以Hello实际上就拿到了one、two两个属性,如果没有三个点的话,Hello拿到的实际上就是props对象,使用的时候还需要自己从中取出变量和值

    三、调用react提供的setProps()函数(几乎不用)

    JavaScript

    var instance=React.render(<HelloWorld></HelloWorld>,document.body); instance.setProps({name:"winty"});

    1
    2
    var instance=React.render(<HelloWorld></HelloWorld>,document.body);
    instance.setProps({name:"winty"});

    状态的含义:

    state,状态是由事物自行处理、不断变化的

    状态的用法:

    getInitialState:初始化实例的状态

    setState:更新组件状态,一旦更新了状态,那么就会触发diff算法,检查内容是否发生变化,若有变化则更新组件,否则就不用。

    属性和状态对比

    相似点:都是纯JS对象、都会触发render更新、都具有确定性。

    新葡亰496net 4

    新葡亰496netjs深入学习详细解析,js实现原生js拖拽效果及思考。属性和状态区分:组件在运行时需要修改的数据就是状态

    四、React中事件的用法

    事件处理函数:React绑定事件处理器的方法和HTML语法非常类似,所有的事件在命名上与原生的javascript规范一致,并且会在相同的情境下触发。

    编写函数

    handleClick:function(){

    }

    绑定

    onClick={this.handleClick}

    各类事件详细说明:

    ①移动设备上的触摸事件:onTouchCancel、onTouchEnd、onTouchMove、onTouchStart

    ②键盘类事件:onKeyDown、onKeyPress、onKeyUp

    ③剪切类事件:onCopy、onCut、onPaste

    ④表单类:onChange//内容变化即触发、onInput//输入框、onSubmit//禁止表单默认跳转行为

    ⑤事件:onFocus、onBlur

    新葡亰496netjs深入学习详细解析,js实现原生js拖拽效果及思考。⑥UI元素类:onScroll

    ⑦鼠标滚动事件:onWheel

    ⑧鼠标类型:onClick、onContextMenu//右键菜单、onDoubleClick //双击、onMouseDown、onMouseEnter、onMouseLeave、onMouseMove、onMouseOut、onMouseOver、onMouseUp

    ⑨拖拽事件:onDrop、onDrag、onDragEnd、onDragEnter、onDragExit、onDragLeave、onDragOver、onDragStart

    事件对象介绍

    使用方法:就是在编写事件对象处理函数的时候,添加一个参数。拿到这个对象之后,就通过对象的属性来可以获取一些信息。

    例如:

    JavaScript

    handleChange:function(event){ console.log(event.target.value); }

    1
    2
    3
    handleChange:function(event){
        console.log(event.target.value);
    }

    示例中,event就是事件对象,event.target就是事件对象的属性,就是对应的DOM元素,拿到这个元素之后再获取它的值。

    事件对象属性

    通用属性:

    新葡亰496net 5

    其他不同类型的事件有不同的属性,简单了解一下

    新葡亰496net 6

    知道了事件的一些属性,我们就可以很方便地在React中获取这些属性,进行一些逻辑的处理,实现一些复杂的业务功能、页面效果等。

    例如:我们可以利用鼠标事件属性,实时显示鼠标在某个区域的坐标:

    JavaScript

    <script type="text/jsx"> var HelloWorld = React.createClass({ getInitialState: function () { return { x: 0, y: 0 } }, handleMouseMove: function (event) { this.setState({ x: event.clientX, y: event.clientY }); }, render: function () { return <div onMouseMove={this.handleMouseMove} style={{ height: '500px', width: '500px', backgroundColor: 'gray' }}> {this.state.x ', ' this.state.y} </div>; }, }); React.render(<HelloWorld></HelloWorld>, document.body); </script>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <script type="text/jsx">
            var HelloWorld = React.createClass({
                getInitialState: function () {
                    return {
                        x: 0,
                        y: 0
                    }
                },
                handleMouseMove: function (event) {
                    this.setState({
                        x: event.clientX,
                        y: event.clientY
                    });
                },
                render: function () {
                    return <div onMouseMove={this.handleMouseMove} style={{
                        height: '500px',
                        width: '500px',
                        backgroundColor: 'gray'
                    }}>
                    {this.state.x ', ' this.state.y}
                    </div>;
                },
            });
            React.render(<HelloWorld></HelloWorld>, document.body);
        </script>

    五、组件的协同使用

    组件协同使用的定义:组件的协同本质上就是对组件的一种组织、管理方式。

    组件协同使用的目的:逻辑清晰、代码模块化、封装细节、代码可复用。

    组件协同使用的方式:

    ①组件嵌套使用:也就是说,用一个父组件把子组件包裹起来,本质就是父子关系。如下图描述:

    新葡亰496net 7

    实例代码:

    JavaScript

    var React = require('react'); var CommentList=require('./CommentList.jsx'); var CommentForm=require('./commentFrom.jsx'); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> //这是一个组件 <CommentForm /> //这是另一个组件 </div> ); } }); module.exports = CommentBox;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var React = require('react');
    var CommentList=require('./CommentList.jsx');
    var CommentForm=require('./commentFrom.jsx');
     
    var CommentBox = React.createClass({
      render: function() {
        return (
          <div className="commentBox">
            <h1>Comments</h1>
            <CommentList />   //这是一个组件
            <CommentForm />    //这是另一个组件
          </div>
        );
      }
    });
     
    module.exports = CommentBox;

    父子组件之间的通信:

    父组件->子组件:通过属性,父组件把数据通过属性来传递给子组件

    子组件->父组件:本质上,子组件不能向父组件通信。但是可以间接地通过触发事件来通信,也就是委托。

    嵌套组合缺点:

    父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护

    无法掌握所有细节,使用者只知道组件用法,不知道实现细节,遇到问题难以修复

    ②Mixin:也就是可以把相同的代码抽象出来,封装成一个函数,然后再调用。

    Mixin的目的:横向抽离出组件的相似代码

    相似概念:面向切向面编程、插件

    实例代码:

    JavaScript

    var Time=React.createClass({ mixins:[IntervalMixin(1000)], getInitialState:function(){ return {secondElapsed:0}; }, onTick:function(){ this.setState({secondElapsed:this.state.secondElapsed 1}); }, render:function(){ return ( <div>Seconds Elapsed:{this.state.secondsElapsed}</div> ); } });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var Time=React.createClass({
        mixins:[IntervalMixin(1000)],
        getInitialState:function(){
           return {secondElapsed:0};
        },
        onTick:function(){
        this.setState({secondElapsed:this.state.secondElapsed 1});
        },
        render:function(){
        return (
           <div>Seconds Elapsed:{this.state.secondsElapsed}</div>
        );
        }
    });

    mixin相当简单,它们就是混合进组件类中的对象而已。React在这方面实现得更加深入,它能防止静默函数覆盖,同时还支持多个mixin混合。但是这些功能在别的系统中可能引起冲突。例如:

    JavaScript

    React.createClass({ mixins:[{ getInitialState:function(){ return {a:1}} }], getInitialState:function(){ return {b:2}} });

    1
    2
    3
    4
    5
    6
    React.createClass({
        mixins:[{
          getInitialState:function(){  return {a:1}}
        }],
        getInitialState:function(){  return {b:2}}
    });

    这样在mixin和组件类中同时定义了getInitialState方法,得到的初始state是{a:1,b:2}.如果mixin中的方法和组件类中的方法返回的对象中存在重复的键,React会抛出一个错误来警示这个问题。

     六、React中的双向绑定

    React创立的理念跟angular那些框架就是不同的,React是单向数据绑定的。那么怎么实现像angular那样的双向绑定效果呢?看代码:

    XHTML

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>React中的双向数据绑定</title> </head> <body> <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script> <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script> <script type="text/jsx"> var BindingMixin = { handleChange: function(key) { var that = this var newState = {} return function(event) { newState[key] = event.target.value that.setState(newState) } } } var BindingExample = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function() { return { text: '', comment: '', } }, render: function() { return <div> <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} /> <textarea valueLink={this.linkState('comment')}></textarea> <h3>{this.state.text}</h3> <h3>{this.state.comment}</h3> </div> } }) React.render(<BindingExample></BindingExample>, document.body); </script> </body> </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <!DOCTYPE html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>React中的双向数据绑定</title>
    </head>
    <body>
        <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script>
        <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script>
        <script type="text/jsx">
            var BindingMixin = {
                handleChange: function(key) {
                    var that = this
                    var newState = {}
                    return function(event) {  
                        newState[key] = event.target.value
                        that.setState(newState)
                    }
                }
            }
            var BindingExample = React.createClass({
                mixins: [React.addons.LinkedStateMixin],
                getInitialState: function() {
                    return {
                        text: '',
                        comment: '',
                    }
                },
                render: function() {
                    return <div>
                        <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} />
                        <textarea valueLink={this.linkState('comment')}></textarea>
                        <h3>{this.state.text}</h3>
                        <h3>{this.state.comment}</h3>
                    </div>
                }
            })
            React.render(<BindingExample></BindingExample>, document.body);
        </script>
    </body>
    </html>

    效果图(没有CSS样式,有点不优雅,见谅):

    新葡亰496net 8

    更多学习demo已上传至:

    参考资料:

    《React引领未来的用户界面开发框架》

    极客学院视频课程

    打赏支持我写出更多好文章,谢谢!

    打赏作者

        表单组件两种类型:约束组件和无约束组件

    *通过createElement创建元素 HELLO Word

    使用 create-react-app 快速构建 React 开发环境

    $ cnpm install -g create-react-app
    $ create-react-app my-app
    $ cd my-app/
    $ npm start
    

    项目的目录结构如下:

    my-app/
      README.md
      node_modules/
      package.json
      .gitignore
      public/
        favicon.ico
        index.html
      src/
        App.css
        App.js
        App.test.js
        index.css
        index.js
        logo.svg
    

    打赏支持我写出更多好文章,谢谢!

    任选一种支付方式

    新葡亰496net 9 新葡亰496net 10

    1 赞 5 收藏 评论

    打赏支持我写出更多好文章,谢谢!

    任选一种支付方式

    新葡亰496net 11 新葡亰496net 12

    1 赞 3 收藏 评论

        1. 无约束组件:

    var el=React.createElement(type,[props],[children...]) 标签 属性 内容
    React.render(el,document.getElementById("..."))

    React JSX

    你的 React JSX 代码可以放在一个独立文件上,例如我们创建一个 helloworld_react.js 文件,代码如下:

    ReactDOM.render(
      <h1>Hello, world!</h1>,
      document.getElementById('example')
    );
    

    然后在 HTML 文件中引入该 JS 文件:

    <body>
      <div id="example"></div>
    <script type="text/babel" src="helloworld_react.js"></script>
    </body>
    
    var myStyle = {
        fontSize: 100,
        color: '#FF0000'
    };
    ReactDOM.render(
        <h1 style = {myStyle}>菜鸟教程</h1>,
        document.getElementById('example')
    );
    
    var arr = [
      <h1>菜鸟教程</h1>,
      <h2>学的不仅是技术,更是梦想!</h2>,
    ];
    ReactDOM.render(
      <div>{arr}</div>,
      document.getElementById('example')
    );
    
    1. 可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中

    2. 在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代

    3. 注释需要写在花括号中

    4. 要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名;要渲染 React 组件,只需创建一个大写字母开头的本地变量

    关于作者:winty

    新葡亰496net 13

    前端工程师,前端爱好者。博客: 个人主页 · 我的文章 · 1 ·  

    新葡亰496net 14

    关于作者:winty

    新葡亰496net 15

    前端工程师,前端爱好者。博客: 个人主页 · 我的文章 · 1 ·  

    新葡亰496net 16

            eg:

    *虚拟DOM

    React 组件

    var HelloMessage = React.createClass({
      render: function() {
        return <h1>Hello World!</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage />,
      document.getElementById('example')
    );
    

    React.createClass 方法用于生成一个组件类 HelloMessage。<HelloMessage /> 实例组件类并输出信息。

    注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。

    如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:

    var HelloMessage = React.createClass({
      render: function() {
        return <h1>Hello {this.props.name}</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage name="Runoob" />,
      document.getElementById('example')
    );
    

    以上实例中 name 属性通过 this.props.name 来获取。

    注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

    var MyForm = React.createClass({

    在虚拟DOM上操作 通过render来挂载到真实的DOM
    组件
    React.createClass(meta)
    内部需要render函数

    复合组件

    我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。

    var WebSite = React.createClass({
      render: function() {
        return (
          <div>
            <Name name={this.props.name} />
            <Link site={this.props.site} />
          </div>
        );
      }
    });
    
    var Name = React.createClass({
      render: function() {
        return (
          <h1>{this.props.name}</h1>
        );
      }
    });
    
    var Link = React.createClass({
      render: function() {
        return (
          <a href={this.props.site}>
            {this.props.site}
          </a>
        );
      }
    });
    
    ReactDOM.render(
      <WebSite name="菜鸟教程" site=" http://www.runoob.com" />,
      document.getElementById('example')
    );
    

    实例中 WebSite 组件使用了 Name 和 Link 组件来输出对应的信息,也就是说 WebSite 拥有 Name 和 Link 的实例。

        render: function() {

    *JSX

    React State(状态)

    (React 把组件看成是一个状态机(State Machines),通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM))

    getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件.

     var LikeButton = React.createClass({
            getInitialState: function() {
              return {liked: false};
            },
            handleClick: function(event) {
              this.setState({liked: !this.state.liked});
      },
      render: function() {
        var text = this.state.liked ? '喜欢' : '不喜欢';
        return (
          <p onClick={this.handleClick}>
            你<b>{text}</b>我。点我切换状态。
          </p>
        );
      }
    });
    
    ReactDOM.render(
      <LikeButton />,
      document.getElementById('example')
    );
    

            return <input type="text" defaultValue="Hello World!"/>;

    JSX是对JavaScript语法的扩展,它让我们可以在JavaScript代码中以类似HTML 的方式创建React元素。
    var Jsxdemo=React.createClass({
    render:function(){
    var html=<div>
    <div className="ez-led">Hello, React!</div>
    <div className="ez-led">2015-04-15</div>
    <div className="ez-led">我是第三排</div>
    </div>;
    return html;
    }
    JSX 能让我们像是拼写字符串一样去写HTML、

    React Props

    state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。

        }

    *props

    使用 Props

    以下实例演示了如何在组件中使用 props:

    var HelloMessage = React.createClass({
      render: function() {
        return <h1>Hello {this.props.name}</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage name="Runoob" />,
      document.getElementById('example')
    

    实例中 name 属性通过 this.props.name 来获取。

    });

    props 称之为 无状态组件 组件的表现都是通过外部传入的props属性 根据自身的状态来做出不同的反应
    var Jsxdemo=React.createClass({
    render:function(){
    var number=this.props.setid;
    alert(number); 这里能直接输出对象里的汉字
    var style={
    "color":"red",
    "fontSize":"12px"//这里是要求内联样式需要按照驼峰写法去写
    }
    var html=<div>
    <div className="ez-led" style={style}>Hello, React!</div>
    <div className="ez-led">2015-04-15</div>
    <div className="ez-led">我是第三排</div>
    </div>;
    return html;
    }
    });

    默认 Props

    你可以通过 getDefaultProps() 方法为 props 设置默认值,实例如下:

    var HelloMessage = React.createClass({
      getDefaultProps: function() {
        return {
          name: 'Runoob'
        };
      },
      render: function() {
        return <h1>Hello {this.props.name}</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage />,
      document.getElementById('example')
    );
    

            组件的value并非由父组件设置,而是让<input/>自己控制自己的值。

        ReactDOM.render(<Jsxdemo setid="11"/>,document.getElementById("jsxdemobox"));
    

    State 和 Props

    我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。

    var WebSite = React.createClass({
      getInitialState: function() {
        return {
          name: "菜鸟教程",
          site: "http://www.runoob.com"
        };
      },
    
      render: function() {
        return (
          <div>
            <Name name={this.state.name} />
            <Link site={this.state.site} />
          </div>
        );
      }
    });
    
    var Name = React.createClass({
      render: function() {
        return (
          <h1>{this.props.name}</h1>
        );
      }
    });
    
    var Link = React.createClass({
      render: function() {
        return (
          <a href={this.props.site}>
            {this.props.site}
          </a>
        );
      }
    });
    
    ReactDOM.render(
      <WebSite />,
      document.getElementById('example')
    );
    

            一个无约束的组件没有太大用处,除非可以访问它的值。可以通过给<input/>添加一个ref属性以访问到DOM节点的值。ref是一个不属于DOM属性的特殊属性。可以通过this上下文访问这个节点,所有的ref都添加到了this.refs上。

    *内联样式

    Props 验证

    Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。
    以下实例创建一个 Mytitle 组件,属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 :

    var title = "菜鸟教程";
    // var title = 123;
    var MyTitle = React.createClass({
      propTypes: {
        title: React.PropTypes.string.isRequired,
      },
    
      render: function() {
         return <h1> {this.props.title} </h1>;
       }
    });
    ReactDOM.render(
        <MyTitle title={title} />,
        document.getElementById('example')
    );
    

    更多验证器说明如下:

    React.createClass({
      propTypes: {
        // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
       optionalArray: React.PropTypes.array,
        optionalBool: React.PropTypes.bool,
        optionalFunc: React.PropTypes.func,
        optionalNumber: React.PropTypes.number,
        optionalObject: React.PropTypes.object,
        optionalString: React.PropTypes.string,
    
        // 可以被渲染的对象 numbers, strings, elements 或 array
        optionalNode: React.PropTypes.node,
    
        //  React 元素
        optionalElement: React.PropTypes.element,
    
        // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
        optionalMessage: React.PropTypes.instanceOf(Message),
    
        // 用 enum 来限制 prop 只接受指定的值。
        optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
    
        // 可以是多个对象类型中的一个
        optionalUnion: React.PropTypes.oneOfType([
          React.PropTypes.string,
          React.PropTypes.number,
          React.PropTypes.instanceOf(Message)
        ]),
    
        // 指定类型组成的数组
        optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
    
        // 指定类型的属性构成的对象
        optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
    
        // 特定 shape 参数的对象
        optionalObjectWithShape: React.PropTypes.shape({
          color: React.PropTypes.string,
          fontSize: React.PropTypes.number
        }),
    
        // 任意类型加上 `isRequired` 来使 prop 不可空。
        requiredFunc: React.PropTypes.func.isRequired,
    
        // 不可空的任意类型
        requiredAny: React.PropTypes.any.isRequired,
    
        // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
        customProp: function(props, propName, componentName) {
          if (!/matchme/.test(props[propName])) {
            return new Error('Validation failed!');
          }
        }
      },
      /* ... */
    });
    

            eg:调用value:

    var Jsxdemo=React.createClass({
    render:function(){
    var style={
    "color":"red",
    "fontSize":"12px"//这里是要求内联样式需要按照驼峰写法去写
    }
    var html=<div>
    <div className="ez-led" style={style}>Hello, React!</div>
    <div className="ez-led">2015-04-15</div>
    <div className="ez-led">我是第三排</div>
    </div>;
    return html;
    }
    });

    React 组件 API

    设置状态:setState
    替换状态:replaceState
    设置属性:setProps
    替换属性:replaceProps
    强制更新:forceUpdate
    获取DOM节点:findDOMNode
    判断组件挂载状态:isMounted

    var MyForm = React.createClass({

    *state 状态机

    设置状态:setState

    setState(object nextState[, function callback])
    
    • 参数说明
      • nextState,将要设置的新状态,该状态会和当前的state合并
      • callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。
        合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。

    关于setState
    1. 不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
    2. setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
    3. setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。

    var Counter = React.createClass({
      getInitialState: function () {
        return { clickCount: 0 };
      },
      handleClick: function () {
        this.setState(function(state) {
          return {clickCount: state.clickCount   1};
        });
      },
      render: function () {
        return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>);
      }
    });
    ReactDOM.render(
      <Counter />,
      document.getElementById('message')
    );
    

    实例中通过点击 h2 标签来使得点击计数器加 1。

        submitHandler: function(event) {

    state - 组件的状态变量 保存组件的当前状态,可以再任何时候通过this.state来获取到当前状态
    getInitialState() - 设置组件初始状态
    setState(currentState) - 设置组件当前状态 会重新渲染
    //getInitialState方法来设置初始化状态 也就是设置我们的 state {key:value} 其中key代表state指向的状态变量 value代表状态
    getInitialState : function(){
    return {open : true};
    },
    //这里是通过一个点击事件来重新设定状态机 必须要通过this.setState({option:!this.state.open}) 意思就是设置状态机的另一种状态
    onClick : function(){
    //读取并重设状态,这将触发重新渲染
    this.setState({open : !this.state.open});
    },
    //在render来操控我们的虚拟DOM 记得return HTML代码
    render : function(){
    //根据状态设置样式
    img = this.state.open ? "img/switch-on.png" : img = "img/switch-off.png";

    替换状态:replaceState

    replaceState(object nextState[, function callback])
    
    • nextState,将要设置的新状态,该状态会替换当前的state。
    • callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

    replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。

            event.preventDefault();

                //返回元素
                return <img src = {img} style={{width:"150px"}} onClick={this.onClick}/>;
            }
    

    设置属性:setProps

    setProps(object nextProps[, function callback])
    
    • nextProps,将要设置的新属性,该状态会和当前的props合并
    • callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。

    设置组件属性,并重新渲染组件。props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。

            //通过ref访问输入框

    • 生命周期

    替换属性:replaceProps

    replaceProps(object nextProps[, function callback])
    
    • nextProps,将要设置的新属性,该属性会替换当前的props。
    • callback,可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。

    replaceProps()方法与setProps类似,但它会删除原有props

            var helloTo = this.refs.helloTo.getDOMNode().value;

    componentWillMount() - 组件实例即将挂接(初次渲染)时被调用
    这个方法在整个生命周期中只会被调用一次。
    componentDidMount() - 组件实例挂接(初次渲染)后被调用
    这个方法在整个生命周期中只会被调用一次。
    componentWillReceiveProps(nextProps) - 组件实例即将设置新属性时被调用
    参数nextProps表示即将应用到组件实例上的新属性值。
    这个方法在初次渲染时不会被调用。在此方法内调用setState()不会引起重新渲染。
    shouldComponentUpdate(nextProps, nextState) - 组件实例即将重新渲染时被调用
    参数nextProps传入即将应用到组件实例上的新属性值,参数nextState传入组件实例即将被 设置的状态值。如果这个方法返回false,那么组件实例就不会被重新渲染。除非我们明确地 知道,新的属性和状态不需要进行重新渲染,否则这个方法都应该返回true。
    这个方法在初次渲染时或通过forceUpdate()方法进行渲染时不会被调用。
    componentWillUpdate(nextProps, nextState) - 组件实例即将重新渲染时被调用
    这个方法在初次渲染时不会被调用。注意:不能在此方法内调用setState()。
    componentDidUpdate(prevProps, prevState) - 组件实例重新渲染后被调用
    这个方法在初次渲染时不会被调用。
    componentWillUnmount() - 组件实例即将从DOM树移除时被调用
    这个方法在整个生命周期中只会被调用一次。

    强制更新:forceUpdate

    forceUpdate([function callback])
    

    参数说明

    • callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。
    1. forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
    2. forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
    3. 一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。

            alert(helloTo);

    (访问DOM v0.14 版中 refs 指向的就是 DOM 节点,同时也会保留 .getDOMNode() 方法(带 warning),最终在 v0.15 版中去除该方法。)
    首先要给你想获得DOM对象设定 ref=“q” ref 必须是全局唯一的
    var el = React.findDOMNode(this.refs.q),
    this.refs.q获取到的是虚拟DOM,在render方法执行之后,并且react已经完成了DOM的更新,才能通过 this.refs.city.getDOMNode() 来拿到原生的DOM元素。
    使用 this.refs.xxx.getDOMNode() 或React.findDOMNode(this.refs.xxx) 可以获取到真正的 DOM 节点。

    获取DOM节点:findDOMNode

    DOMElement findDOMNode()
    

    返回值:DOM元素DOMElement

    如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。

        }

    // 之前:
    // var input = this.refs.giraffe.getDOMNode();
    //
    // v0.14 版:0.15版本以后
    var input = this.refs.giraffe;
    alert(input.value);

    判断组件挂载状态:isMounted

    bool isMounted()
    返回值:true或false,表示组件是否已挂载到DOM中
    isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

    React 组件生命周期
    组件的生命周期可分成三个状态:
    Mounting:已插入真实 DOM
    Updating:正在被重新渲染
    Unmounting:已移出真实 DOM
    生命周期的方法有:
    componentWillMount 在渲染前调用,在客户端也在服务端。
    componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。
    componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。
    shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
    可以在你确认不需要更新组件时使用。
    componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
    componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
    componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。
    以下实例在 Hello 组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒重新设置组件的透明度,并重新渲染:
    React 实例
    var Hello = React.createClass({
    getInitialState: function () {
    return {
    opacity: 1.0
    };
    },

    componentDidMount: function () {
    this.timer = setInterval(function () {
    var opacity = this.state.opacity;
    opacity -= .05;
    if (opacity < 0.1) {
    opacity = 1.0;
    }
    this.setState({
    opacity: opacity
    });
    }.bind(this), 100);
    },

    render: function () {
    return (
    <div style={{opacity: this.state.opacity}}>
    Hello {this.props.name}
    </div>
    );
    }
    });

    ReactDOM.render(
    <Hello name="world"/>,
    document.body
    );

    以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中。
    React 实例
    var Button = React.createClass({
    getInitialState: function() {
    return {
    data:0
    };
    },
    setNewNumber: function() {
    this.setState({data: this.state.data 1})
    },
    render: function () {
    return (
    <div>
    <button onClick = {this.setNewNumber}>INCREMENT</button>
    <Content myNumber = {this.state.data}></Content>
    </div>
    );
    }
    })
    var Content = React.createClass({
    componentWillMount:function() {
    console.log('Component WILL MOUNT!')
    },
    componentDidMount:function() {
    console.log('Component DID MOUNT!')
    },
    componentWillReceiveProps:function(newProps) {
    console.log('Component WILL RECEIVE PROPS!')
    },
    shouldComponentUpdate:function(newProps, newState) {
    return true;
    },
    componentWillUpdate:function(nextProps, nextState) {
    console.log('Component WILL UPDATE!');
    },
    componentDidUpdate:function(prevProps, prevState) {
    console.log('Component DID UPDATE!')
    },
    componentWillUnmount:function() {
    console.log('Component WILL UNMOUNT!')
    },

    render: function () {
      return (
        <div>
          <h3>{this.props.myNumber}</h3>
        </div>
      );
    }
    

    });
    ReactDOM.render(
    <div>
    <Button />
    </div>,
    document.getElementById('example')
    );

    React AJAX
    React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
    当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
    以下实例演示了获取 Github 用户最新 gist 共享描述:
    React 实例
    var UserGist = React.createClass({
    getInitialState: function() {
    return {
    username: '',
    lastGistUrl: ''
    };
    },

    componentDidMount: function() {
    this.serverRequest = $.get(this.props.source, function (result) {
    var lastGist = result[0];
    this.setState({
    username: lastGist.owner.login,
    lastGistUrl: lastGist.html_url
    });
    }.bind(this));
    },

    componentWillUnmount: function() {
    this.serverRequest.abort();
    },

    render: function() {
    return (
    <div>
    {this.state.username} 用户最新的 Gist 共享地址:
    <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
    </div>
    );
    }
    });

    ReactDOM.render(
    <UserGist source="" />,
    document.getElementById('example')
    );

    React 表单与事件
    在实例中我们设置了输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state。我们可以使用 onChange 事件来监听 input 的变化,并修改 state。
    React 实例
    var HelloMessage = React.createClass({
    getInitialState: function() {
    return {value: 'Hello Runoob!'};
    },
    handleChange: function(event) {
    this.setState({value: event.target.value});
    },
    render: function() {
    var value = this.state.value;
    return <div>
    <input type="text" value={value} onChange={this.handleChange} />
    <h4>{value}</h4>
    </div>;
    }
    });
    ReactDOM.render(
    <HelloMessage />,
    document.getElementById('example')
    );

    上面的代码将渲染出一个值为 Hello Runoob! 的 input 元素,并通过 onChange 事件响应更新用户输入的值。
    实例 2
    在以下实例中我们将为大家演示如何在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。
    你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。
    React 实例
    var Content = React.createClass({
    render: function() {
    return <div>
    <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} />
    <h4>{this.props.myDataProp}</h4>
    </div>;
    }
    });
    var HelloMessage = React.createClass({
    getInitialState: function() {
    return {value: 'Hello Runoob!'};
    },
    handleChange: function(event) {
    this.setState({value: event.target.value});
    },
    render: function() {
    var value = this.state.value;
    return <div>
    <Content myDataProp = {value}
    updateStateProp = {this.handleChange}></Content>
    </div>;
    }
    });
    ReactDOM.render(
    <HelloMessage />,
    document.getElementById('example')
    );

    React 事件
    以下实例演示通过 onClick 事件来修改数据:
    React 实例
    var HelloMessage = React.createClass({
    getInitialState: function() {
    return {value: 'Hello Runoob!'};
    },
    handleChange: function(event) {
    this.setState({value: '菜鸟教程'})
    },
    render: function() {
    var value = this.state.value;
    return <div>
    <button onClick={this.handleChange}>点我</button>
    <h4>{value}</h4>
    </div>;
    }
    });
    ReactDOM.render(
    <HelloMessage />,
    document.getElementById('example')
    );

    当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下:
    React 实例
    var Content = React.createClass({
    render: function() {
    return <div>
    <button onClick = {this.props.updateStateProp}>点我</button>
    <h4>{this.props.myDataProp}</h4>
    </div>
    }
    });
    var HelloMessage = React.createClass({
    getInitialState: function() {
    return {value: 'Hello Runoob!'};
    },
    handleChange: function(event) {
    this.setState({value: '菜鸟教程'})
    },
    render: function() {
    var value = this.state.value;
    return <div>
    <Content myDataProp = {value}
    updateStateProp = {this.handleChange}></Content>
    </div>;
    }
    });
    ReactDOM.render(
    新葡亰496net,<HelloMessage />,
    document.getElementById('example')
    );

    React Refs
    可以用来绑定到 render() 输出的任何组件上,允许你引用 render() 返回的相应的支撑实例,确保在任何时间总是拿到正确的实例
    使用方法
    绑定一个 ref 属性到 render 的返回值上:
    <input ref="myInput" />
    在其它代码中,通过 this.refs 获取支撑实例:
    var input = this.refs.myInput;
    var inputValue = input.value;
    var inputRect = input.getBoundingClientRect();
    完整实例
    你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下:
    React 实例
    var MyComponent = React.createClass({
    handleClick: function() {
    // 使用原生的 DOM API 获取焦点
    this.refs.myInput.focus();
    },
    render: function() {
    // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
    <div>
    <input type="text" ref="myInput" />
    <input
    type="button"
    value="点我输入框获取焦点"
    onClick={this.handleClick}
    />
    </div>
    );
    }
    });

    ReactDOM.render(
    <MyComponent />,
    document.getElementById('example')
    );

        render: function() {

    *表单

            return (

    文本输入框
    不要使用value属性设置文本输入框元素的初值,应当使用defaultValue:
    //JSX
    <input type ="text" defaultValue ="demo"/>
    复选按钮
    不要使用checked属性设置复选按钮的初始选中状态,应当使用defaultChecked:
    //JSX
    <input type ="checkbox" defaultChecked/>
    单选按钮组
    不要使用option元素的selected属性设置单选按钮组的初始选中状态,应当使用 select元素的defaultValue:
    //JSX
    <select defaultValue="A">
    <option value="A">China</option>
    <option value="B">India</option>
    <option value="C">Japan</option>
    </select>

                <form onSubmit={this.submitHandler}>

    *容器组件

                    <input ref="helloTo" type="text" defaultValue="Hello World!"/>

    在ReactDOM.render里面 ,组件要成双标签 {this.props.children}用于获取到我们的React的 子元素

                    <br />

    ReactDOM.render(<Jsxdemo setid="11">我是容器组件</Jsxdemo>,document.getElementById("jsxdemobox"));
    var Jsxdemo=React.createClass({
    componentDidMount:function(){
    var message=this.refs.bbbb;
    // alert(message.value);
    },
    render:function(){
    var number=this.props.setid;
    // alert(number);
    var style={
    "color":"red",
    "fontSize":"12px"//这里是要求内联样式需要按照驼峰写法去写
    }
    var html=<div>
    <div className="ez-led" style={style}>{this.props.children}</div>
    <div className="ez-led" ref="aaaa">2015-04-15</div>
    <input type="text" className="ez-led" ref="bbbb" defaultValue="我是第三排"/>
    </div>;
    return html;
    }
    });

                    <button type="submit">Speak</button>

    ReactDOM.render(<Jsxdemo setid="11">我是容器组件</Jsxdemo>,document.getElementById("jsxdemobox"));
    

                </form>

    *JSX可展开属性

            );

    我们可以再render里面

        }

    <div className="ez-slider" onMouseDown ={this.onMouseDown} onMouseMove ={this.onMouseMove} onMouseUp ={this.onMouseUp}/>
    相等于
    var props ={
    className :"ez-slider",
    onMouseDown :this.onMouseDown,
    onMouseUp :this.onMouseUp,
    onMouseMove :this.onMouseMove
    };

    });

    //传入属性包
    var rel =<div {...props}></div>;

        2. 约束组件:

    var Jsxdemo=React.createClass({
    // getInitialState:function(){

            约束组件的模式与React其他类型组件的模式一致。表单的状态交由React组件控制。状态值被存储在React组件的state中。

            // },
            componentDidMount:function(){
                var message=this.refs.bbbb;
                // alert(message.value);
            },
            onClick:function(){
                alert(0);
            },
            render:function(){
                var number=this.props.setid;
                // alert(number);
                var style={
                    "color":"red",
                    "fontSize":"12px"//这里是要求内联样式需要按照驼峰写法去写
                }
                var options={
                    className:"ez-led",
                    onClick:this.onClick
                }
                var newhtml=<div {...options}>22222</div>;
                return newhtml;
            }
        });
    
    ReactDOM.render(<Jsxdemo setid="11">我是容器组件</Jsxdemo>,document.getElementById("jsxdemobox"));
    

            约束组件能更好的控制表单组件。在约束组件中,输入框的值是由父组件社设置的。

    动画 CSS3 transition 思路就是利用状态机来判断 DOM状态
    为元素声明transition样式
    设置属性初始值,第一次渲染元素
    设置属性目标值,第二次渲染元素

            eg:

    *默认属性

    var MyForm = React.createClass({    

    getDefaultProps:是设置默认属性 红色为相关代码
    如果设置了value 则 弹出 10 如果没有设置 则 弹出 20

        getInitialState: function() {

    var ZZ=React.createClass({
        getDefaultProps:function(){
            return {
                value:20
            }
        },
        onClick:function(){
            alert(0);
        },
        render:function(){
            alert(this.props.value);
            var option={
                className:"maincsss",
                onClick:this.onClick
            }
            var html=<div {...option}>111111</div>;
            return html;    
        }
    });
    ReactDOM.render(<ZZ value="10"/>,document.getElementById("mainbox"));
    
    mixin复用代码      meisen发音  混合柔和的意思  专门用来写公共模块的对象 并且通过minxins指向您的 mixin对象 来拷贝你的React组件中
    

            return {

    varEzLoggerMixin={
    log:function(){
    //sth. happened here.
    }
    };
    React.createClass({
    mixins:[EzLoggerMixin],
    render:function(){
    //your render stuff.
    }
    });

                helloTo: "Hello World!"

    //mixin就是存放公共能力的一个简单的对象而已。首字母可不大写 但是为了养成习惯 首字母还是大写的好 哦
    var Minxintext={
    log:function(){
    alert("我是mixin");
    }
    };
    mixins : [Minxintext],
    然后在React实例里面的生命周期或者事件函数里面 通过 this. 你定义的mixin对象内部的函数

            };

    var Minxintext={
    log:function(){
    alert("我是mixin");
    }
    };
    var ZZ=React.createClass({
    mixins : [Minxintext],
    getDefaultProps:function(){
    return {
    value:20
    }
    },
    onClick:function(){
    this.log();
    },
    render:function(){
    // alert(this.props.value);
    var option={
    className:"maincsss",
    onClick:this.onClick
    }
    var html=<div {...option}>111111</div>;
    return html;
    }
    });
    ReactDOM.render(<ZZ value="10"/>,document.getElementById("mainbox"));

        }

    map 循环

        handleChange: function(event) {

    return (
    <span>
    {
    datas.map(function(i){
    return <span {...option} key={i.id}>我是{i.name}a a a </span>;
    })
    }
    </span>
    )

            this.setState({

                helloTo: event.target.value

            });

        }

        submitHandler: function(event) {

            event.preventDefault();

            //通过ref访问输入框

            alert(this.state.helloTo);

        }

        render: function() {

            return (

                <form onSubmit={this.submitHandler}>

                    <input type="text" value={this.state.helloTo} onChange={this.handleChange}/>

                    <br />

                    <button type="submit">Speak</button>

                </form>

            );

        }

    });

            约束组件可以控制数据流,在用户输入数据时更新state。如将用户输入的字符转成变大写(如:this.setState({helloTo: event.target.value.toUpperCase()});)并添加到输入框时不会发生闪烁。这是因为React拦截了浏览器原生的change事件,在setState被调用后,这个组件就会重新渲染输入框。然后React计算差异,更新输入框的值。

        3. 表单事件:

            React支持所有HTML事件。这些事件遵循驼峰命名的约定,且会被转成合成事件。这些事件是标准化的,提供了跨浏览器的一致接口。

            所有合成事件都提供了event.target来访问触发事件的DOM节点。

            访问约束组件最简单的方式之一:

    handleEvent: function(syntheticEvent) {

        var DOMNode = syntheticEvent.target;

        var newValue = DOMNode.value;

    }

        4. Label:

            Label是表单元素中重要组件,可以明确地向用户传达你的要求,提升单选框和复选框的可用性。

            React中class变成className,for变为htmlFor:

    <label className="col-sm-3 control-label no-padding-right">开户行<span className="red">*</span></label>

        5. 文本框和Select:

            React中的<textarea/>和<select/>:(约束的)

            

    <textarea value={this.state.value} onChange={this.handleChange} />

    <select value={this.state.value} onChange={this.handleChange}>

        <option value="grapefruit">Grapefruit</option>

        <option value="lime">Lime</option>

        <option value="coconut">Coconut</option>

        <option value="mango">Mango</option>

    </select>

            多选时可在select后加上multi={true}属性

            当使用多选的select时,select组件的值不会更新,只有选项的selected属性会发生变化。可以使用ref或event.target来访问选项,检查它们是否被选中。

            eg:

    handleChange: function(event) {

        var checked = [];

        var sel = event.target;

        for(var i = 0; i < sel.length; i ) {

            var value = sel.value[i];

            if (value.selected) {

                checked.push(value.value);

            }

        }

     }

        6. 复选框和单选框:

            类型为checkbox或radio的<input/>与类型为text的<input/>的行为完全不一样。通常复选框和单选框的值是不变的,只有checked状态会变化。所以要控制复选框或单选框就要控制它们的checked属性。也可以在非约束的复选框或者单选框中使用defaultChecked。

    <input type="checkbox" className="ace"

        checked={this.state.outboundLogisticsStatus == "SENTED"}

        onChange={this.handleLogisticsStatusChange}/>

        <span className="lbl">推送出库单

    </span>

        7. 表单元素的name属性:

            在React中,name属性对于表单元素来说并没有那么重要,因为约束表单组件已经把值存储到了state中,并且表单的提交事件也会被拦截。在获取表单值的时候,name属性并不是必须的。对于非约束的表单组件来说,也可以使用refs来直接访问表单元素。

            那么属性的作用:

                -- name属性可以让第三方表单序列化类库在React中正常工作;

                -- 对于仍然使用传统提交方式的表单来说,name属性是必须的;

                -- 在用户浏览器中,name被用在自动填写常用信息中,比如用户地址;

                -- 对于非约束的单选框组件,name是有必要的,它可以作为这些组件分组的依据,确保在同一时刻,同一个表单中拥有相同name的单选框只有一个可以被选中。如果不使用name属性,这一行为可以使用约束的单选框实现。

        8. 多个表单元素与change处理器:

            重用事件处理器:

                -- 通过.bind传递其他参数

    var MyForm = React.createClass({

        getInitialState: function () {

            return {

                given_name: "",

                family_name: ""

            };

        },

        handleChange: function (name, event) {

            var newState = {};

            newState[name] = event.target.value;

            this.setState(newState);

        },

        submitHandler: function (event) {

            event.preventDefault();

            var words = [

                "Hi",

                this.state.given_name,

                this.state.family_name

            ];

            alert(words.join(" "));

        },

        render: function () {

            return <form onSubmit={this.submitHandler}>

                <label htmlFor="given_name">Given Name:</label>

                <br />

                <input

                    type="text"

                    name="given_name"

                    value={this.state.given_name}

                    onChange={this.handleChange.bind(this,'given_name')}/>

                <br />

                <label htmlFor="family_name">Family Name:</label>

                <br />

                <input

                    type="text"

                    name="family_name"

                    value={this.state.family_name}

                    onChange={this.handleChange.bind(this,'family_name')}/>

                <br />

                <button type="submit">Speak</button>

            </form>;

        }

    });

                -- 使用DOMNode的name属性来判断需要更新哪个组件的状态

    var MyForm = React.createClass({

        getInitialState: function () {

            return {

                given_name: "",

                family_name: ""

            };

        },

        handleChange: function (event) {

            var newState = {};

            newState[event.target.name] = event.target.value;

            this.setState(newState);

        },

        submitHandler: function (event) {

            event.preventDefault();

            var words = [

                "Hi",

                this.state.given_name,

                this.state.family_name

            ];

            alert(words.join(" "));

        },

        render: function () {

            return <form onSubmit={this.submitHandler}>

            <label htmlFor="given_name">Given Name:</label>

            <br />

            <input

                type="text"

                name="given_name"

                value={this.state.given_name}

                onChange={this.handleChange}/>

            <br />

            <label htmlFor="family_name">Family Name:</label>

            <br />

            <input

                type="text"

                name="family_name"

                value={this.state.family_name}

                onChange={this.handleChange}/>

            <br />

            <button type="submit">Speak</button>

            </form>;

        }

    });

                -- React.addons.LinkedStateMixmin为组件提供一个linkState方法。linkState返回一个对象,包含value和requestChange两个属性。

                    value根据提供的name属性从state中获取对应的值

                    requestChange是一个函数,使用新的值更新同名的state

                        eg:

    this.linkState('given_name');

    //返回

    {

        value: this.state.given_name

        requestChange: function (newValue) {

           this.setState({

              given_name: newValue

           });

        },

    }

                   需要把这个对象传递给一个React特有的非DOM属性valueLink。valueLink使用对象提供的value更新表单域的值,并提供一个onChange处理器,当表单域更新时使用新的值调用requestChange。

    var MyForm = React.createClass({

        mixins: [React.addons.LinkedStateMixin],

        getInitialState: function () {

            return {

                given_name: "",

                family_name: ""

            };

        },

        submitHandler: function (event) {

            event.preventDefault();

            var words = [

                "Hi",

                this.state.given_name,

                this.state.family_name

            ];

            alert(words.join(" "));

        },

        render: function () {

            return <form onSubmit={this.submitHandler}>

                <label htmlFor="given_name">Given Name:</label>

                <br />

                <input

                    type="text"

                    name="given_name"

                    valueLink={this.linkState('given_name')} />

                <br />

                <label htmlFor="family_name">Family Name:</label>

                <br />

                <input

                    type="text"

                    name="family_name"

                    valueLink={this.linkState('family_name')} />

                <br />

                <button type="submit">Speak</button>

            </form>;

        }

    });

                    这种方法便于控制表单域,把其值保存在父组件中的state中。而且,其数据流仍然与其他约束的表单元素保持一致。

                    但是使用这种方式往数据流中添加定制功能时,复杂度会增加。建议只在特定的场景下使用。因为传统约束表单组件提供了同样的功能且更加灵活。

        9. 自定义表单组件:

            可以在项目中复用共有功能。也是一种将交互界面提升为一种更加复杂的表单组件(如单选框、多选框)的好方法。

            eg:自定义表单单选框和valueLink结合使用:

    <div className="col-sm-10">

        <PaymentDistrictSelect valueLink={this.linkState('paymentDistrictCode')}/>

    </div>

        10. Focus:

            控制表单组件的focus可以很好地引导用户按照表单逻辑逐步填写。可减少用户操作,增强可用性。

     

        11. 可用性:

            React组件常常缺乏可用性。如缺乏对键盘操作的支持。

        12. 传达要求:

            placeholder可以用来显示输入实例或作为没有输入时的默认值

    <input type="text" name="keyword" placeholder="对账单号/预付单号" valueLink={this.linkState("keyword")} style={{width: '100%'}}/>
    

    本文由新葡亰496net发布于新葡亰官网,转载请注明出处:新葡亰496netjs深入学习详细解析,js实现原生js拖

    关键词: