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>
组件协同使用介绍
什么是组件协同使用
组建的协同本质上市对组件的一宗组织、管理方式目的: 逻辑清晰 代码模块化 封装细节 代码可复用
如何实现组件的协同使用
组件嵌套
含义
组件嵌套实质上是父子关系
通信方式
父组件------属性------>子组件父组件<--事件处理函数--子组件 //实质上是委托
优点
逻辑清晰:父子关系很好理解代码模块化:每个模块对应一个功能,不同模块可以同步开发封装细节:开发者只需要关注组件的功能,不用关心组件的实现细节
缺点
编写难度高:父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护无法掌握所有细节:使用者只知道组件用法,不知道细节,遇到问题难以修复
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
- reactjs学习手记(3)
- reactjs学习手记(1)
- reactjs学习手记(2)
- ReactJS学习系列课程1(ReactJS简介)
- ReactJS学习系列课程3(React State状态)
- ReactJs 学习
- ReactJs学习
- Reactjs相关实例学习【Reactjs】
- (记录向)reactjs学习记录
- ReactJS学习系列课程(JSX语法)
- jquery学习手记(3)属性
- Linux.NET学习手记(3)
- FotoVision学习手记(3)
- CORBA学习手记3
- [TensorFlow学习手记] 3
- ReactJS入门学习一
- ReactJS入门学习二
- ReactJS入门学习二
- reactjs学习手记(1)
- linux nginx的https
- 线段树,方差,数学(Variance,玲珑杯 Round#5 H lonlife 1063)
- poj 3641 Pseudoprime numbers
- reactjs学习手记(2)
- reactjs学习手记(3)
- 动态代理和静态代理
- BITCS2016程序设计 | 29. 微处理器模拟
- 【工具】[Listary]好用到哭的快速搜索工具
- 21.无限分类表的数据库设计
- java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
- Spark在爱奇艺的应用实践
- Ural1982-Electrification Plan
- MyBatis批量更新