reactjs学习手记(3)

来源:互联网 发布:测量长度的软件 编辑:程序博客网 时间:2024/05/29 10:29

React中事件的用法

概要

事件处理函数的使用

编写时间处理函数

组件    -->     React自有方法   render、componentWillUpdate、、、        -->     用户自定义方法  handleClick、handleChange、handleMouseover事件处理函数 可以接收一个event参数

绑定事件处理函数

onClick={this.handleClick}      //传入的包含所有方法的对象触摸事件                //只会在移动端触发onTouchCancelonTouchEndonTouchMoveonTouchStart键盘onKeyDownonKeyPressOnKeyUp剪切onCopyonCutonPaste表单onChangeonInputonSubmit焦点onFocus                 //得到焦点onBlur                  //失去焦点UI元素onScroll滚动onWheel鼠标onClickonContextMenu           //鼠标右键onDoubleClickonMouseDownonMouseEnteronMouseLeaveonMouseMoveonMouseOutonMouseOveronMouseUp鼠标拖拽onDrop                  //松开鼠标?onDragonDragEndonDragEnteronDragExitonDragLeaveonDragOveronDragStart

demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({        handleChange:function(event){            console.log(event.target.value);        },        render: function(){            return <div>            <input onChange={this.handleChange} />            </div>        }    });    var instance = React.render(<Hello></Hello>,document.body);</script>

事件对象的介绍

事件对象使用方式

handleChange:function(event){           //event是事件对象    console.log(event.target.value);    //target就是事件对象的属性}

不同事件对象介绍

通用

boolean bubbles                 //是否可以冒泡boolean cancelable              //        取消DOMEventTarget currentTarget    //boolean defaultPrevented        //事件是否禁止默认行为number eventPhase               //事件所处的阶段boolean isTrusted               //事件是否可信  是否由用户触发DOMEvent nativeEvent            //拿到原生的eventvoid preventDeafault()          //禁止默认行为void stopPropagation()          //阻止冒泡DOMEventTarget target           //number timeStop                 //事件触发的时间string type                     //事件触发的类型

剪切

DOMDataTransfer clipboardData   //

键盘事件

boolean altKey                  //是否按下了altNumber charCode                 //字符编码boolean ctrlKey                 //是否function getModifierState(key)  //是否按下了辅助按键String key                      //Number keyCode                  //不是字符String locale                   //本地化的Number location                 //位置boolean metaKey                 //win键 或 花键boolean repeat                  //是否重复boolean shiftKey                //Number which                    //

焦点

DOMEventTarget relatedTarget    //两个焦点之间的关联

鼠标

boolean altKeyNumber buttonNumber buttonsNumber clientXNumber clientYboolean ctrlKeyfunction getModifierState(key)boolean metaKeyNumber pageXNumber pageYDOMEventTarget relatedTargetNumber screenXNumber screenYboolean shiftKey

触摸

boolean altKey                     //DOMTouchList changedTouches        //*boolean ctrlKey                    //function getModifierState(key)     //boolean metaKey                    //boolean shiftKey                   //DOMTouchList targetTouches         //*DOMTouchList touches               //*

UI元素

Number detail                   //DOMAbstractView                 //

鼠标滚轮滚动

Number deltaMode                //Number deltaX                   //Number deltaY                   //Number deltaZ                   //

demo

滚轮滚动改变颜色

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({        getInitialState:function(){            return {                backgroundColor:'#FFFFFF'            }        },        handleWheel:function(event){            var newColor = (parseInt(this.state.backgroundColor.substr(1),16) + event.deltaY * 997).toString(16);            newColor = '#' + newColor.substr(newColor.length - 6).toUpperCase();            this.setState({                backgroundColor:newColor            });        },        render: function(){            console.log(this.state);            return <div onWheel={this.handleWheel} style={this.state}>            <p>Hello</p>            </div>        }    });    var instance = React.render(<Hello></Hello>,document.body);</script>

密码示例

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({        getInitialState:function(){            return {                password:''            }        },        handleKeyPress:function(event){            this.setState({                password:this.state.password + event.which            });            console.log("before update:");            console.log(this.state);        },        componentDidUpdate:function(){            console.log("after update:");            console.log(this.state);        },        handleChange:function(event){            event.value = '';        },        render: function(){            return <div>                <input  onKeyPress={this.handleKeyPress} onChange={this.handleChange}></input>                <p style={{'display':this.state.password.indexOf('495051')>=0?'inline':'none'}}>You got it!</p>            </div>;        }    });    var instance = React.render(<Hello></Hello>,document.body);</script>

事件和关联状态

事件和状态关联

handleChange:function(event){    this.setState({inputText:event.target.value});}

demo

记录鼠标移动坐标

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({        getInitialState:function(){            return {                x:0,                y:0            }        },        handleMouseMove:function(event){            this.setState({                x:event.clientX,                y:event.clientY            });            console.log("before update:");            console.log(this.state);        },        componentDidUpdate:function(){            console.log("after update:");            console.log(this.state);        },        render: function(){            return <div onMouseMove={this.handleMouseMove} style={{height:'1000px',              width:'700px'            }}>{this.state.x + ' , ' + this.state.y}            </div>;        }    });    var instance = React.render(<Hello></Hello>,document.body);</script>

组件协同使用介绍

什么是组件协同使用

组建的协同本质上市对组件的一宗组织、管理方式目的:    逻辑清晰    代码模块化    封装细节    代码可复用

如何实现组件的协同使用

xy

组件嵌套

zujian

含义

组件嵌套实质上是父子关系

通信方式

父组件------属性------>子组件父组件<--事件处理函数--子组件 //实质上是委托

优点

逻辑清晰:父子关系很好理解代码模块化:每个模块对应一个功能,不同模块可以同步开发封装细节:开发者只需要关注组件的功能,不用关心组件的实现细节

缺点

编写难度高:父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护无法掌握所有细节:使用者只知道组件用法,不知道细节,遇到问题难以修复

demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var GenderSelect = React.createClass({        render:function(){            return <select onChange={this.props.handleSelect}>                <option value="0">男</option>                <option value="1">女</option>            </select>        }    });    var SignupForm = React.createClass({        getInitialState:function(){            return {                name:'',                password:'',                gender:''            }        },        handleChange:function(name,event){            var newState = {};            newState[name] = event.target.value;            this.setState(newState);        },        handleSelect:function(event){            this.setState({gender:event.target.value});        },        render: function(){            console.log(this.state);            return <form>                <input type="text" placeholder="username..." onChange={this.handleChange.bind(this,'name')} />                <input type="password" placeholder="password..." onChange={this.handleChange.bind(this,'password')} />                <GenderSelect handleSelect={this.handleSelect}></GenderSelect>            </form>;        }    });    var instance = React.render(<SignupForm></SignupForm>,document.body);</script>

Mixin编写和使用

this.handleClick = function(){  //Mixin    $.ajax(...)    ...}

Mixin的含义

Mixin=一组方法Mixin的目的是横向抽离出组件的相似代码相似概念:面向切面编程、插件
var SetIntervalMixin = {    componentWillMount:function(){        this.intervals = [];    },    setInterval:function(){        this.intervals.push(setInterval.apply(null,arguments));    },    componentWillUnmount:function(){        this.intervals.map(clearInterval);    }};var TickTock = React.createClass({    mixins:[SetIntervalMixin]   //Use the mixin    getInitialState:function(){        return {seconds:0};    },})

优点:

代码复用:抽离出通用代码,减少开发成本,提高开发效率即插即用:可以直接使用许多现有的Mixin来编写自己的组件适应性强:改动一次代码,影响多个组件

缺点

编写难度高:Mixin可能被用在各种环境中,兼容多种环境就需要更多的逻辑和代码,通用的代价是提高复杂度降低代码可读性:组件的优势在于将逻辑和见面直接结合在一起,Mixin本质山会分散逻辑,理解起来难度更大

React双向绑定Mixin

非Mixin

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var BindingExample = React.createClass({        getInitialState:function(){            return {                text:''            };        },        handleChange:function(event){            this.setState({text:event.target.value});        },        render: function(){            console.log(this.state);            return <div>                <input type="text" placeholder="please input..." onChange={this.handleChange} />                <p>{this.state.text}</p>            </div>;        }    });    var instance = React.render(<BindingExample></BindingExample>,document.body);</script>

Mixin写法

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var BindingMixin = {        handleChange: function(key){            var that = this;            return function(event){                var newState = {};                newState[key] = event.target.value;                that.setState(newState);            }        }    }    var BindingExample = React.createClass({        mixins:[BindingMixin],        getInitialState:function(){            return {                text:''            };        },        render: function(){            console.log(this.state);            return <div>                <input type="text" placeholder="please input..." onChange={this.handleChange('text')} />                <p>{this.state.text}</p>            </div>;        }    });    var instance = React.render(<BindingExample></BindingExample>,document.body);</script>

表单详解

不可控组件和可控组件

什么是不可控组件

状态存储组件数据<input type="text" defaultValue="Hello World!" />   //数据写死在属性中,导致组件中数据和state中数据可能不再互相对应,组件中的数据对于整个组件来说不可控var inputValue=???var inputValue=React.findDOMNode(this.refs.input).value

什么是可控组件

<input type="text" defaultValue="{this.state.value}" />   var inputValue=this.state.value

为什么组件要可控

组件可控的好处    符合React的数据流    数据存储在state中,便于使用    便于对数据进行处理

实例演示

不可控demo

demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    /*var MyForm = React.createClass({        render: function(){            return <input type="text" defaultValue="Hello"/>        }    });    var instance = React.render(<MyForm></MyForm>,document.body);    */    var MyForm = React.createClass({        submitHandler:function(event){            event.preventDefault();            var helloTo = React.findDOMNode(this.refs.helloTo).value;            alert(helloTo);        },          render:function(){              return <form onSubmit={this.submitHandler}>                <input type="text" ref="helloTo" defaultValue="Hello World!" />                <br />                <button type="submit">Speak</button>            </form>;        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

可控demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var MyForm = React.createClass({        getInitialState:function(){            return {                helloTo:"Hello World!"            };        },        handleChange:function(event){            this.setState({                helloTo:event.target.value            });        },        submitHandler:function(event){            event.preventDefault();            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>;        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

不同表单元素的使用

表单元素介绍

label       <label htmlFor="name">Name</label>      //不常用、可由placeholder替代input       <input type="checkbox" value="A" checked = {this.state.checked} onChange={this.handleChange} />      //***textarea    <textarea value={this.state.helloTo} onChange={this.handleChange} />select      <select value={this.state.heloTo} onChange={this.handleChange}>                <option value="1">一</option>                <option value="2">二</option>            </select>

实例演示

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var MyForm = React.createClass({        getInitialState:function(){            return {                username:"",                gender:"man",                checked:false            };        },        handleChange:function(name,event){            var that = this;            return function(event){                var newState = {};                var a;                if(name=='checked'){                    if(this.props.checked){     //此处只能使用this.props.checked                        newState[name] = false;                    } else {                        newState[name] = true;                    }                }else{                    newState[name] = event.target.value;                }                that.setState(newState);            }        },        submitHandler:function(event){            event.preventDefault();            if(this.state.checked)              //此处只能使用this.state.checked            console.log(this.state);            else            console.log("please agree the license");        },          render:function(){              return <form onSubmit={this.submitHandler}>                <label htmlFor="username">input username...</label>                <input id="username" type="text" value={this.state.username} onChange={this.handleChange('username')} />                <br />                <select value={this.state.gender} onChange={this.handleChange('gender')}>                    <option value="man">nan</option>                    <option value="woman">nv</option>                </select>                <br />                <label htmlFor="checkbox">agree user license</label>                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange('checked')} />                <button type="submit">register</button>            </form>        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

事件处理函数复用

为什么要复用事件处理函数

功能相同的函数,不好维护    onChange={this.handleChange1}    onChange={this.handleChange2}    onChange={this.handleChange3}    onChange={this.handleChange4}    onChange={this.handleChange5}    onChange={this.handleChange6}更好的写法    onChange={this.handleChange}    //并且由它处理函数细节

事件处理函数的两种复用方式

bind复用

handleChange:function(name,event){    ...}{this.handleChange.bind(this,'input1')}

name复用

handleChange:function(event){    var name = event.target.name;   //需要额外添加属性}{this.handleChange}

demo

bind复用

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var MyForm = React.createClass({        getInitialState:function(){            return {                username:"",                gender:"man",                checked:false            };        },        handleChange:function(name,event){            var newState = {};            var a;            newState[name] = name=="checked"?event.target.checked:event.target.value;            this.setState(newState);        },        submitHandler:function(event){            event.preventDefault();            if(this.state.checked)              //此处只能使用this.state.checked            console.log(this.state);            else            console.log("please agree the license");        },          render:function(){              return <form onSubmit={this.submitHandler}>                <label htmlFor="username">input username...</label>                <input id="username" type="text" value={this.state.username} onChange={this.handleChange.bind(this,'username')} />                <br />                <select value={this.state.gender} onChange={this.handleChange.bind(this,'gender')}>                    <option value="man">nan</option>                    <option value="woman">nv</option>                </select>                <br />                <label htmlFor="checkbox">agree user license</label>                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange.bind(this,'checked')} />                <button type="submit">register</button>            </form>        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

name复用

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var MyForm = React.createClass({        getInitialState:function(){            return {                username:"",                gender:"man",                checked:true            };        },        handleChange:function(event){            var newState = {};            console.log(event.target.checked);            newState[event.target.name] = event.target.name=="checked"?event.target.checked:event.target.value;            this.setState(newState);        },        submitHandler:function(event){            event.preventDefault();            if(this.state.checked)              //此处只能使用this.state.checked            console.log(this.state);            else            console.log("please agree the license");        },          render:function(){              return <form onSubmit={this.submitHandler}>                <label htmlFor="username">input username...</label>                <input name="username" id="username" type="text" value={this.state.username} onChange={this.handleChange} />                <br />                <select name="gender" value={this.state.gender} onChange={this.handleChange}>                    <option value="man">nan</option>                    <option value="woman">nv</option>                </select>                <br />                <label htmlFor="checkbox">agree user license</label>                <input name="checked" id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange} />                <button type="submit">register</button>            </form>        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

函数复用???

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var MyForm = React.createClass({        getInitialState:function(){            return {                username:"",                gender:"man",                checked:false            };        },        handleChange:function(name,event){            var that = this;            return function(event){                var newState = {};                var a;                if(name=='checked'){                    if(this.props.checked){     //此处只能使用this.props.checked                        newState[name] = false;                    } else {                        newState[name] = true;                    }                }else{                    newState[name] = event.target.value;                }                that.setState(newState);            }        },        submitHandler:function(event){            event.preventDefault();            if(this.state.checked)              //此处只能使用this.state.checked            console.log(this.state);            else            console.log("please agree the license");        },          render:function(){              return <form onSubmit={this.submitHandler}>                <label htmlFor="username">input username...</label>                <input id="username" type="text" value={this.state.username} onChange={this.handleChange('username')} />                <br />                <select value={this.state.gender} onChange={this.handleChange('gender')}>                    <option value="man">nan</option>                    <option value="woman">nv</option>                </select>                <br />                <label htmlFor="checkbox">agree user license</label>                <input id="checkbox" type="checkbox" checked={this.state.checked} onChange={this.handleChange('checked')} />                <button type="submit">register</button>            </form>        }    });    var instance = React.render(<MyForm></MyForm>,document.body);</script>

表单组件自定义

为什么要自定义表单组件

内因

表单本省具备特殊性:样式统一、信息内聚、行为固定

外因

本质上是组件嵌套,组织和管理组件的一种方式

表单组件的两种定义方式

不可控的自定义组件

不推荐的方式

可控的自定义组件

0 0