事件处理
在React中获取虚拟组件中的标签的值
-
使用组件的 refs属性
-
在虚拟组件的标签中定义事件,在事件中通过 箭头函数 获取标签的值
-
使用事件对象——event
事件处理:
-
通过onXxx属性指定事件处理函数(注意大小写)
-
React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 ———为了更好的兼容性
-
React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ————为了高效
-
通过event.target得到发生事件的DOM元素对象 ———不要过度使用ref
使用event.target属性:
class Demo extends React.Component{ myRef = React.createRef() showData = (event)=>{ alert(event.target.value); } render(){ return( <div> <input onBlur={this.showData} type="text" placeholder="失去焦点提示数据"/> </div> ) } } ReactDOM.render(<Demo/>,document.getElementById('test'))
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
React事件处理和Dom事件处理区别:
1、在 语法 上的不同点:
-
React事件名采用驼峰命名法,即事件名首字母大写。如onclick(Dom)——onClick(React)
-
响应事件的函数在React中以 对象方式 赋值,Dom是以 字符串方式 赋值
<button onclick= ' clickMe( ) '>提交</button> ——Dom方式 <button onClick={ clickMe( ) }>提交</button> ——React方式
2、在阻止事件的默认行为有区别:React事件是合成的,DOM事件是原生的
-
Dom:返回false
-
React:显示的调用事件对象event.preventDefault
React事件处理函数
-
1、使用ES6的箭头函数
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } handleClick=()=>{ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>点我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example'));
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
2、在组件中定义事件处理函数
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } this.handleClick=this.handleClick.bind(this); } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>点我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example'));
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
注:这种方法的好处是每次render渲染都不会重新创建一个回调函数,没有额外的性能损失,但是如果在一个组件中有很多的事件函数时这种在构造函数中绑定this的方法会显得繁琐
-
3、在给事件赋值时绑定this
class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick.bind(this)}>点我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example'));
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
注:但是此方法在每次render时都会重新创建一个新的函数,性能有一定的损失,但在事件处理函数需要传参数时,这种方法就比较好
事件流
在该示例中,3个div嵌套显示,并且每个元素上均绑定onClick事件。当用户点击红色区域的div元素时,可以看到,控制台先后输出了child -> parent -> ancestor,这是因为在React的事件处理系统中,默认的事件流就是冒泡。
const style={ child:{ width:'100px', height:'100px', background:'red' }, parent:{ width:'150px', height:'150px', background:'blue' }, ancestor:{ width:'200px', height:'200px', background:'green' } } class Example extends React.Component{ render(){ return( <div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}> <div onClickCapture={ ()=> console.log('parent')} style={style.parent}> <div onClickCapture={ ()=> console.log('child')} style={style.child}></div> </div> </div> ) } } ReactDOM.render(<Example/>,document.getElementById('example'));
-
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
-
React默认的事件触发方式:冒泡方式
-
若将事件触发改为捕获方式:需要在事件名后带上 Capture 后缀
<div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}> <div onClickCapture={ ()=> console.log('parent')} style={style.parent}> <div onClickCapture={ ()=> console.log('child')} style={style.child}></div> </div> </div>
事件委托
在合成事件系统中,所有的事件都是绑定在document元素上,即虽然在某个React元素上绑定了事件,但是,最后事件都委托给document统一触发。因此,在合成事件中只能阻止合成事件中的事件传播
React 阻止的事件流,并没有阻止真正DOM元素的事件触发,还是按照冒泡的方式,层层将事件交给上级元素进行处理,最后事件传播到docuement,触发合成事件,在合成事件中,child触发时,e.stopPropagation() 被调用,合成事件中的事件被终止。因此,合成事件中的stopPropagation无法阻止事件在真正元素上的传递,它只阻止合成事件中的事件流。相反,如果绑定一个真正的事件,那么,合成事件则会被终止。
-
默认事件流是冒泡的,所有事件统一由document触发,在React中阻止冒泡方法是调用e.stopPropagation()
-
React的合成事件是可以找到原生的事件对象
-
React中的合成事件中只有一个全局对象event,该对象不是原生的event,但通过它可以获得event对象的部分属性。每个事件触发完后React的全局对象event就会被清空,因此不能在异步操作使用
事件类型:
收集表单数据
非受控组件
表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用 ref 从DOM获取表单值),即不受React控制改变表单元素提交的值的方式,称为:“非受控组件”
class Login extends React.Component{ handleSubmit = (event)=>{ event.preventDefault() const {username,password} = this alert(`你输入的用户名是:${username.value},你输入的密码是:${password.value}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用户名:<input ref={c => this.username = c} type="text" name="username"/> 密码:<input ref={c => this.password = c} type="password" name="password"/> <button>登录</button> </form> ) } } ReactDOM.render(<Login/>,document.getElementById('test'))
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
受控组件
在HTML中,标签<input>
、<textarea>
、<select>
的值的改变通常是根据用户输入进行更新。在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。
class Login extends React.Component{ state = { username:'', password:'' } saveUsername = (event)=>{ this.setState({username:event.target.value}) } savePassword = (event)=>{ this.setState({password:event.target.value}) } handleSubmit = (event)=>{ event.preventDefault() const {username,password} = this.state alert(`你输入的用户名是:${username},你输入的密码是:${password}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用户名:<input onChange={this.saveUsername} type="text" name="username"/> 密码:<input onChange={this.savePassword} type="password" name="password"/> <button>登录</button> </form> ) } } ReactDOM.render(<Login/>,document.getElementById('test'))
-
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
受控和非受控元素都有其优点,根据具体情况选择
特征
|
非受控制
|
受控
|
一次性检索(例如表单提交)
|
√
|
√
|
及时验证
|
×
|
√
|
有条件的禁用提交按钮
|
×
|
√
|
执行输入格式
|
×
|
√
|
一个数据的几个输入
|
×
|
√
|
动态输入
|
×
|
√
|
函数柯里化
高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。
-
若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
-
若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
常见的高阶函数有:Promise、setTimeout、arr.map()等等
函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。
function sum(a){ return(b)=>{ return (c)=>{ return a+b+c } } }
函数柯里化的实现
class Login extends React.Component{ state = { username:'', password:'' } saveFormData = (dataType)=>{ return (event)=>{ this.setState({[dataType]:event.target.value}) } } handleSubmit = (event)=>{ event.preventDefault() const {username,password} = this.state alert(`你输入的用户名是:${username},你输入的密码是:${password}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/> 密码:<input onChange={this.saveFormData('password')} type="password" name="password"/> <button>登录</button> </form> ) } } ReactDOM.render(<Login/>,document.getElementById('test'))
-
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
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。
分享此文一切功德,皆悉回向给文章原作者及众读者.
转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务